~thomas-voss/location-service/refactor-location-position

« back to all changes in this revision

Viewing changes to 3rd-party/ichnaea/src/ichnaea/util/json.hpp

  • Committer: Thomas Voß
  • Date: 2016-08-14 19:36:05 UTC
  • Revision ID: thomas.voss@canonical.com-20160814193605-e6c0xitja9yncmw8
Add back mls provider relying on Mozilla's location service.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*!
 
2
@mainpage
 
3
 
 
4
These pages contain the API documentation of JSON for Modern C++, a C++11
 
5
header-only JSON class.
 
6
 
 
7
Class @ref nlohmann::basic_json is a good entry point for the documentation.
 
8
 
 
9
@copyright The code is licensed under the [MIT
 
10
  License](http://opensource.org/licenses/MIT):
 
11
  <br>
 
12
  Copyright &copy; 2013-2015 Niels Lohmann.
 
13
  <br>
 
14
  Permission is hereby granted, free of charge, to any person obtaining a copy
 
15
  of this software and associated documentation files (the "Software"), to deal
 
16
  in the Software without restriction, including without limitation the rights
 
17
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
18
  copies of the Software, and to permit persons to whom the Software is
 
19
  furnished to do so, subject to the following conditions:
 
20
  <br>
 
21
  The above copyright notice and this permission notice shall be included in
 
22
  all copies or substantial portions of the Software.
 
23
  <br>
 
24
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
25
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
26
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
27
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
28
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
29
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
30
  SOFTWARE.
 
31
 
 
32
@author [Niels Lohmann](http://nlohmann.me)
 
33
@see https://github.com/nlohmann/json to download the source code
 
34
 
 
35
@version 1.0.0
 
36
*/
 
37
 
 
38
#ifndef NLOHMANN_JSON_HPP
 
39
#define NLOHMANN_JSON_HPP
 
40
 
 
41
#include <algorithm>
 
42
#include <array>
 
43
#include <ciso646>
 
44
#include <cmath>
 
45
#include <cstdio>
 
46
#include <functional>
 
47
#include <initializer_list>
 
48
#include <iomanip>
 
49
#include <iostream>
 
50
#include <iterator>
 
51
#include <limits>
 
52
#include <map>
 
53
#include <memory>
 
54
#include <sstream>
 
55
#include <string>
 
56
#include <type_traits>
 
57
#include <utility>
 
58
#include <vector>
 
59
 
 
60
// enable ssize_t on MinGW
 
61
#ifdef __GNUC__
 
62
    #ifdef __MINGW32__
 
63
        #include <sys/types.h>
 
64
    #endif
 
65
#endif
 
66
 
 
67
// enable ssize_t for MSVC
 
68
#ifdef _MSC_VER
 
69
    #include <basetsd.h>
 
70
    using ssize_t = SSIZE_T;
 
71
#endif
 
72
 
 
73
/*!
 
74
@brief namespace for Niels Lohmann
 
75
@see https://github.com/nlohmann
 
76
@since version 1.0.0
 
77
*/
 
78
namespace nlohmann
 
79
{
 
80
 
 
81
 
 
82
/*!
 
83
@brief unnamed namespace with internal helper functions
 
84
@since version 1.0.0
 
85
*/
 
86
namespace
 
87
{
 
88
/*!
 
89
@brief Helper to determine whether there's a key_type for T.
 
90
@sa http://stackoverflow.com/a/7728728/266378
 
91
*/
 
92
template<typename T>
 
93
struct has_mapped_type
 
94
{
 
95
  private:
 
96
    template<typename C> static char test(typename C::mapped_type*);
 
97
    template<typename C> static int  test(...);
 
98
  public:
 
99
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
 
100
};
 
101
 
 
102
/// "equality" comparison for floating point numbers
 
103
template<typename T>
 
104
static bool approx(const T a, const T b)
 
105
{
 
106
    return not (a > b or a < b);
 
107
}
 
108
}
 
109
 
 
110
/*!
 
111
@brief a class to store JSON values
 
112
 
 
113
@tparam ObjectType type for JSON objects (@c std::map by default; will be used
 
114
in @ref object_t)
 
115
@tparam ArrayType type for JSON arrays (@c std::vector by default; will be used
 
116
in @ref array_t)
 
117
@tparam StringType type for JSON strings and object keys (@c std::string by
 
118
default; will be used in @ref string_t)
 
119
@tparam BooleanType type for JSON booleans (@c `bool` by default; will be used
 
120
in @ref boolean_t)
 
121
@tparam NumberIntegerType type for JSON integer numbers (@c `int64_t` by
 
122
default; will be used in @ref number_integer_t)
 
123
@tparam NumberFloatType type for JSON floating-point numbers (@c `double` by
 
124
default; will be used in @ref number_float_t)
 
125
@tparam AllocatorType type of the allocator to use (@c `std::allocator` by
 
126
default)
 
127
 
 
128
@requirement The class satisfies the following concept requirements:
 
129
- Basic
 
130
 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
 
131
   JSON values can be default constructed. The result will be a JSON null value.
 
132
 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
 
133
   A JSON value can be constructed from an rvalue argument.
 
134
 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
 
135
   A JSON value can be copy-constrcuted from an lvalue expression.
 
136
 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
 
137
   A JSON value van be assigned from an rvalue argument.
 
138
 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
 
139
   A JSON value can be copy-assigned from an lvalue expression.
 
140
 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
 
141
   JSON values can be destructed.
 
142
- Layout
 
143
 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
 
144
   JSON values have
 
145
   [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
 
146
   All non-static data members are private and standard layout types, the class
 
147
   has no virtual functions or (virtual) base classes.
 
148
- Library-wide
 
149
 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
 
150
   JSON values can be compared with `==`, see @ref
 
151
   operator==(const_reference,const_reference).
 
152
 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
 
153
   JSON values can be compared with `<`, see @ref
 
154
   operator<(const_reference,const_reference).
 
155
 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
 
156
   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
 
157
   other compatible types, using unqualified function call @ref swap().
 
158
 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
 
159
   JSON values can be compared against `std::nullptr_t` objects which are used
 
160
   to model the `null` value.
 
161
- Container
 
162
 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
 
163
   JSON values can be used like STL containers and provide iterator access.
 
164
 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
 
165
   JSON values can be used like STL containers and provide reverse iterator
 
166
   access.
 
167
 
 
168
@internal
 
169
@note ObjectType trick from http://stackoverflow.com/a/9860911
 
170
@endinternal
 
171
 
 
172
@see RFC 7159 <http://rfc7159.net/rfc7159>
 
173
 
 
174
@since version 1.0.0
 
175
 
 
176
@nosubgrouping
 
177
*/
 
178
template <
 
179
    template<typename U, typename V, typename... Args> class ObjectType = std::map,
 
180
    template<typename U, typename... Args> class ArrayType = std::vector,
 
181
    class StringType = std::string,
 
182
    class BooleanType = bool,
 
183
    class NumberIntegerType = int64_t,
 
184
    class NumberFloatType = double,
 
185
    template<typename U> class AllocatorType = std::allocator
 
186
    >
 
187
class basic_json
 
188
{
 
189
  private:
 
190
    /// workaround type for MSVC
 
191
    using basic_json_t = basic_json<ObjectType,
 
192
          ArrayType,
 
193
          StringType,
 
194
          BooleanType,
 
195
          NumberIntegerType,
 
196
          NumberFloatType,
 
197
          AllocatorType>;
 
198
 
 
199
  public:
 
200
 
 
201
    /////////////////////
 
202
    // container types //
 
203
    /////////////////////
 
204
 
 
205
    /// @name container types
 
206
    /// @{
 
207
 
 
208
    /// the type of elements in a basic_json container
 
209
    using value_type = basic_json;
 
210
 
 
211
    /// the type of an element reference
 
212
    using reference = value_type&;
 
213
 
 
214
    /// the type of an element const reference
 
215
    using const_reference = const value_type&;
 
216
 
 
217
    /// a type to represent differences between iterators
 
218
    using difference_type = std::ptrdiff_t;
 
219
 
 
220
    /// a type to represent container sizes
 
221
    using size_type = std::size_t;
 
222
 
 
223
    /// the allocator type
 
224
    using allocator_type = AllocatorType<basic_json>;
 
225
 
 
226
    /// the type of an element pointer
 
227
    using pointer = typename std::allocator_traits<allocator_type>::pointer;
 
228
    /// the type of an element const pointer
 
229
    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
 
230
 
 
231
    // forward declaration
 
232
    template<typename Base> class json_reverse_iterator;
 
233
 
 
234
    /// an iterator for a basic_json container
 
235
    class iterator;
 
236
    /// a const iterator for a basic_json container
 
237
    class const_iterator;
 
238
    /// a reverse iterator for a basic_json container
 
239
    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
 
240
    /// a const reverse iterator for a basic_json container
 
241
    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
 
242
 
 
243
    /// @}
 
244
 
 
245
 
 
246
    /*!
 
247
    @brief returns the allocator associated with the container
 
248
    */
 
249
    static allocator_type get_allocator()
 
250
    {
 
251
        return allocator_type();
 
252
    }
 
253
 
 
254
 
 
255
    ///////////////////////////
 
256
    // JSON value data types //
 
257
    ///////////////////////////
 
258
 
 
259
    /// @name JSON value data types
 
260
    /// @{
 
261
 
 
262
    /*!
 
263
    @brief a type for an object
 
264
 
 
265
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
 
266
    > An object is an unordered collection of zero or more name/value pairs,
 
267
    > where a name is a string and a value is a string, number, boolean, null,
 
268
    > object, or array.
 
269
 
 
270
    To store objects in C++, a type is defined by the template parameters
 
271
    described below.
 
272
 
 
273
    @tparam ObjectType  the container to store objects (e.g., `std::map` or
 
274
    `std::unordered_map`)
 
275
    @tparam StringType the type of the keys or names (e.g., `std::string`). The
 
276
    comparison function `std::less<StringType>` is used to order elements
 
277
    inside the container.
 
278
    @tparam AllocatorType the allocator to use for objects (e.g.,
 
279
    `std::allocator`)
 
280
 
 
281
    #### Default type
 
282
 
 
283
    With the default values for @a ObjectType (`std::map`), @a StringType
 
284
    (`std::string`), and @a AllocatorType (`std::allocator`), the default value
 
285
    for @a object_t is:
 
286
 
 
287
    @code {.cpp}
 
288
    std::map<
 
289
      std::string, // key_type
 
290
      basic_json, // value_type
 
291
      std::less<std::string>, // key_compare
 
292
      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
 
293
    >
 
294
    @endcode
 
295
 
 
296
    #### Behavior
 
297
 
 
298
    The choice of @a object_t influences the behavior of the JSON class. With
 
299
    the default type, objects have the following behavior:
 
300
 
 
301
    - When all names are unique, objects will be interoperable in the sense
 
302
      that all software implementations receiving that object will agree on the
 
303
      name-value mappings.
 
304
    - When the names within an object are not unique, later stored name/value
 
305
      pairs overwrite previously stored name/value pairs, leaving the used
 
306
      names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
 
307
      be treated as equal and both stored as `{"key": 1}`.
 
308
    - Internally, name/value pairs are stored in lexicographical order of the
 
309
      names. Objects will also be serialized (see @ref dump) in this order. For
 
310
      instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored and
 
311
      serialized as `{"a": 2, "b": 1}`.
 
312
    - When comparing objects, the order of the name/value pairs is irrelevant.
 
313
      This makes objects interoperable in the sense that they will not be
 
314
      affected by these differences. For instance, `{"b": 1, "a": 2}` and
 
315
      `{"a": 2, "b": 1}` will be treated as equal.
 
316
 
 
317
    #### Limits
 
318
 
 
319
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
 
320
    > An implementation may set limits on the maximum depth of nesting.
 
321
 
 
322
    In this class, the object's limit of nesting is not constraint explicitly.
 
323
    However, a maximum depth of nesting may be introduced by the compiler or
 
324
    runtime environment. A theoretical limit can be queried by calling the @ref
 
325
    max_size function of a JSON object.
 
326
 
 
327
    #### Storage
 
328
 
 
329
    Objects are stored as pointers in a @ref basic_json type. That is, for any
 
330
    access to object values, a pointer of type `object_t*` must be dereferenced.
 
331
 
 
332
    @sa @ref array_t -- type for an array value
 
333
 
 
334
    @since version 1.0.0
 
335
    */
 
336
    using object_t = ObjectType<StringType,
 
337
          basic_json,
 
338
          std::less<StringType>,
 
339
          AllocatorType<std::pair<const StringType,
 
340
          basic_json>>>;
 
341
 
 
342
    /*!
 
343
    @brief a type for an array
 
344
 
 
345
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
 
346
    > An array is an ordered sequence of zero or more values.
 
347
 
 
348
    To store objects in C++, a type is defined by the template parameters
 
349
    explained below.
 
350
 
 
351
    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
 
352
    `std::list`)
 
353
    @tparam AllocatorType  allocator to use for arrays (e.g., `std::allocator`)
 
354
 
 
355
    #### Default type
 
356
 
 
357
    With the default values for @a ArrayType (`std::vector`) and @a
 
358
    AllocatorType (`std::allocator`), the default value for @a array_t is:
 
359
 
 
360
    @code {.cpp}
 
361
    std::vector<
 
362
      basic_json, // value_type
 
363
      std::allocator<basic_json> // allocator_type
 
364
    >
 
365
    @endcode
 
366
 
 
367
    #### Limits
 
368
 
 
369
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
 
370
    > An implementation may set limits on the maximum depth of nesting.
 
371
 
 
372
    In this class, the array's limit of nesting is not constraint explicitly.
 
373
    However, a maximum depth of nesting may be introduced by the compiler or
 
374
    runtime environment. A theoretical limit can be queried by calling the @ref
 
375
    max_size function of a JSON array.
 
376
 
 
377
    #### Storage
 
378
 
 
379
    Arrays are stored as pointers in a @ref basic_json type. That is, for any
 
380
    access to array values, a pointer of type `array_t*` must be dereferenced.
 
381
 
 
382
    @sa @ref object_t -- type for an object value
 
383
 
 
384
    @since version 1.0.0
 
385
    */
 
386
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
 
387
 
 
388
    /*!
 
389
    @brief a type for a string
 
390
 
 
391
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
 
392
    > A string is a sequence of zero or more Unicode characters.
 
393
 
 
394
    To store objects in C++, a type is defined by the template parameter
 
395
    described below. Unicode values are split by the JSON class into byte-sized
 
396
    characters during deserialization.
 
397
 
 
398
    @tparam StringType  the container to store strings (e.g., `std::string`).
 
399
    Note this container is used for keys/names in objects, see @ref object_t.
 
400
 
 
401
    #### Default type
 
402
 
 
403
    With the default values for @a StringType (`std::string`), the default
 
404
    value for @a string_t is:
 
405
 
 
406
    @code {.cpp}
 
407
    std::string
 
408
    @endcode
 
409
 
 
410
    #### String comparison
 
411
 
 
412
    [RFC 7159](http://rfc7159.net/rfc7159) states:
 
413
    > Software implementations are typically required to test names of object
 
414
    > members for equality. Implementations that transform the textual
 
415
    > representation into sequences of Unicode code units and then perform the
 
416
    > comparison numerically, code unit by code unit, are interoperable in the
 
417
    > sense that implementations will agree in all cases on equality or
 
418
    > inequality of two strings. For example, implementations that compare
 
419
    > strings with escaped characters unconverted may incorrectly find that
 
420
    > `"a\\b"` and `"a\u005Cb"` are not equal.
 
421
 
 
422
    This implementation is interoperable as it does compare strings code unit
 
423
    by code unit.
 
424
 
 
425
    #### Storage
 
426
 
 
427
    String values are stored as pointers in a @ref basic_json type. That is,
 
428
    for any access to string values, a pointer of type `string_t*` must be
 
429
    dereferenced.
 
430
 
 
431
    @since version 1.0.0
 
432
    */
 
433
    using string_t = StringType;
 
434
 
 
435
    /*!
 
436
    @brief a type for a boolean
 
437
 
 
438
    [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
 
439
    type which differentiates the two literals `true` and `false`.
 
440
 
 
441
    To store objects in C++, a type is defined by the template parameter @a
 
442
    BooleanType which chooses the type to use.
 
443
 
 
444
    #### Default type
 
445
 
 
446
    With the default values for @a BooleanType (`bool`), the default value for
 
447
    @a boolean_t is:
 
448
 
 
449
    @code {.cpp}
 
450
    bool
 
451
    @endcode
 
452
 
 
453
    #### Storage
 
454
 
 
455
    Boolean values are stored directly inside a @ref basic_json type.
 
456
 
 
457
    @since version 1.0.0
 
458
    */
 
459
    using boolean_t = BooleanType;
 
460
 
 
461
    /*!
 
462
    @brief a type for a number (integer)
 
463
 
 
464
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
 
465
    > The representation of numbers is similar to that used in most programming
 
466
    > languages. A number is represented in base 10 using decimal digits. It
 
467
    > contains an integer component that may be prefixed with an optional minus
 
468
    > sign, which may be followed by a fraction part and/or an exponent part.
 
469
    > Leading zeros are not allowed. (...) Numeric values that cannot be
 
470
    > represented in the grammar below (such as Infinity and NaN) are not
 
471
    > permitted.
 
472
 
 
473
    This description includes both integer and floating-point numbers. However,
 
474
    C++ allows more precise storage if it is known whether the number is an
 
475
    integer or a floating-point number. Therefore, two different types, @ref
 
476
    number_integer_t and @ref number_float_t are used.
 
477
 
 
478
    To store integer numbers in C++, a type is defined by the template
 
479
    parameter @a NumberIntegerType which chooses the type to use.
 
480
 
 
481
    #### Default type
 
482
 
 
483
    With the default values for @a NumberIntegerType (`int64_t`), the default
 
484
    value for @a number_integer_t is:
 
485
 
 
486
    @code {.cpp}
 
487
    int64_t
 
488
    @endcode
 
489
 
 
490
    #### Default behavior
 
491
 
 
492
    - The restrictions about leading zeros is not enforced in C++. Instead,
 
493
      leading zeros in integer literals lead to an interpretation as octal
 
494
      number. Internally, the value will be stored as decimal number. For
 
495
      instance, the C++ integer literal `010` will be serialized to `8`. During
 
496
      deserialization, leading zeros yield an error.
 
497
    - Not-a-number (NaN) values will be serialized to `null`.
 
498
 
 
499
    #### Limits
 
500
 
 
501
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
 
502
    > An implementation may set limits on the range and precision of numbers.
 
503
 
 
504
    When the default type is used, the maximal integer number that can be
 
505
    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
 
506
    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
 
507
    that are out of range will yield over/underflow when used in a constructor.
 
508
    During deserialization, too large or small integer numbers will be
 
509
    automatically be stored as @ref number_float_t.
 
510
 
 
511
    [RFC 7159](http://rfc7159.net/rfc7159) further states:
 
512
    > Note that when such software is used, numbers that are integers and are
 
513
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
 
514
    > that implementations will agree exactly on their numeric values.
 
515
 
 
516
    As this range is a subrange of the exactly supported range [INT64_MIN,
 
517
    INT64_MAX], this class's integer type is interoperable.
 
518
 
 
519
    #### Storage
 
520
 
 
521
    Integer number values are stored directly inside a @ref basic_json type.
 
522
 
 
523
    @sa @ref number_float_t -- type for number values (floating-point)
 
524
 
 
525
    @since version 1.0.0
 
526
    */
 
527
    using number_integer_t = NumberIntegerType;
 
528
 
 
529
    /*!
 
530
    @brief a type for a number (floating-point)
 
531
 
 
532
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
 
533
    > The representation of numbers is similar to that used in most programming
 
534
    > languages. A number is represented in base 10 using decimal digits. It
 
535
    > contains an integer component that may be prefixed with an optional minus
 
536
    > sign, which may be followed by a fraction part and/or an exponent part.
 
537
    > Leading zeros are not allowed. (...) Numeric values that cannot be
 
538
    > represented in the grammar below (such as Infinity and NaN) are not
 
539
    > permitted.
 
540
 
 
541
    This description includes both integer and floating-point numbers. However,
 
542
    C++ allows more precise storage if it is known whether the number is an
 
543
    integer or a floating-point number. Therefore, two different types, @ref
 
544
    number_integer_t and @ref number_float_t are used.
 
545
 
 
546
    To store floating-point numbers in C++, a type is defined by the template
 
547
    parameter @a NumberFloatType which chooses the type to use.
 
548
 
 
549
    #### Default type
 
550
 
 
551
    With the default values for @a NumberFloatType (`double`), the default
 
552
    value for @a number_float_t is:
 
553
 
 
554
    @code {.cpp}
 
555
    double
 
556
    @endcode
 
557
 
 
558
    #### Default behavior
 
559
 
 
560
    - The restrictions about leading zeros is not enforced in C++. Instead,
 
561
      leading zeros in floating-point literals will be ignored. Internally, the
 
562
      value will be stored as decimal number. For instance, the C++
 
563
      floating-point literal `01.2` will be serialized to `1.2`. During
 
564
      deserialization, leading zeros yield an error.
 
565
    - Not-a-number (NaN) values will be serialized to `null`.
 
566
 
 
567
    #### Limits
 
568
 
 
569
    [RFC 7159](http://rfc7159.net/rfc7159) states:
 
570
    > This specification allows implementations to set limits on the range and
 
571
    > precision of numbers accepted. Since software that implements IEEE
 
572
    > 754-2008 binary64 (double precision) numbers is generally available and
 
573
    > widely used, good interoperability can be achieved by implementations that
 
574
    > expect no more precision or range than these provide, in the sense that
 
575
    > implementations will approximate JSON numbers within the expected
 
576
    > precision.
 
577
 
 
578
    This implementation does exactly follow this approach, as it uses double
 
579
    precision floating-point numbers. Note values smaller than
 
580
    `-1.79769313486232e+308` and values greather than `1.79769313486232e+308`
 
581
    will be stored as NaN internally and be serialized to `null`.
 
582
 
 
583
    #### Storage
 
584
 
 
585
    Floating-point number values are stored directly inside a @ref basic_json
 
586
    type.
 
587
 
 
588
    @sa @ref number_integer_t -- type for number values (integer)
 
589
 
 
590
    @since version 1.0.0
 
591
    */
 
592
    using number_float_t = NumberFloatType;
 
593
 
 
594
    /// @}
 
595
 
 
596
 
 
597
    ///////////////////////////
 
598
    // JSON type enumeration //
 
599
    ///////////////////////////
 
600
 
 
601
    /*!
 
602
    @brief the JSON type enumeration
 
603
 
 
604
    This enumeration collects the different JSON types. It is internally used
 
605
    to distinguish the stored values, and the functions @ref is_null(), @ref
 
606
    is_object(), @ref is_array(), @ref is_string(), @ref is_boolean(), @ref
 
607
    is_number(), and @ref is_discarded() rely on it.
 
608
 
 
609
    @since version 1.0.0
 
610
    */
 
611
    enum class value_t : uint8_t
 
612
    {
 
613
        null,           ///< null value
 
614
        object,         ///< object (unordered set of name/value pairs)
 
615
        array,          ///< array (ordered collection of values)
 
616
        string,         ///< string value
 
617
        boolean,        ///< boolean value
 
618
        number_integer, ///< number value (integer)
 
619
        number_float,   ///< number value (floating-point)
 
620
        discarded       ///< discarded by the the parser callback function
 
621
    };
 
622
 
 
623
 
 
624
  private:
 
625
    /// helper for exception-safe object creation
 
626
    template<typename T, typename... Args>
 
627
    static T* create(Args&& ... args)
 
628
    {
 
629
        AllocatorType<T> alloc;
 
630
        auto deleter = [&](T * object)
 
631
        {
 
632
            alloc.deallocate(object, 1);
 
633
        };
 
634
        std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
 
635
        alloc.construct(object.get(), std::forward<Args>(args)...);
 
636
        return object.release();
 
637
    }
 
638
 
 
639
    ////////////////////////
 
640
    // JSON value storage //
 
641
    ////////////////////////
 
642
 
 
643
    /*!
 
644
    @brief a JSON value
 
645
 
 
646
    The actual storage for a JSON value of the @ref basic_json class.
 
647
 
 
648
    @since version 1.0.0
 
649
    */
 
650
    union json_value
 
651
    {
 
652
        /// object (stored with pointer to save storage)
 
653
        object_t* object;
 
654
        /// array (stored with pointer to save storage)
 
655
        array_t* array;
 
656
        /// string (stored with pointer to save storage)
 
657
        string_t* string;
 
658
        /// boolean
 
659
        boolean_t boolean;
 
660
        /// number (integer)
 
661
        number_integer_t number_integer;
 
662
        /// number (floating-point)
 
663
        number_float_t number_float;
 
664
 
 
665
        /// default constructor (for null values)
 
666
        json_value() noexcept = default;
 
667
        /// constructor for booleans
 
668
        json_value(boolean_t v) noexcept : boolean(v) {}
 
669
        /// constructor for numbers (integer)
 
670
        json_value(number_integer_t v) noexcept : number_integer(v) {}
 
671
        /// constructor for numbers (floating-point)
 
672
        json_value(number_float_t v) noexcept : number_float(v) {}
 
673
        /// constructor for empty values of a given type
 
674
        json_value(value_t t)
 
675
        {
 
676
            switch (t)
 
677
            {
 
678
                case value_t::object:
 
679
                {
 
680
                    object = create<object_t>();
 
681
                    break;
 
682
                }
 
683
 
 
684
                case value_t::array:
 
685
                {
 
686
                    array = create<array_t>();
 
687
                    break;
 
688
                }
 
689
 
 
690
                case value_t::string:
 
691
                {
 
692
                    string = create<string_t>("");
 
693
                    break;
 
694
                }
 
695
 
 
696
                case value_t::boolean:
 
697
                {
 
698
                    boolean = boolean_t(false);
 
699
                    break;
 
700
                }
 
701
 
 
702
                case value_t::number_integer:
 
703
                {
 
704
                    number_integer = number_integer_t(0);
 
705
                    break;
 
706
                }
 
707
 
 
708
                case value_t::number_float:
 
709
                {
 
710
                    number_float = number_float_t(0.0);
 
711
                    break;
 
712
                }
 
713
 
 
714
                default:
 
715
                {
 
716
                    break;
 
717
                }
 
718
            }
 
719
        }
 
720
 
 
721
        /// constructor for strings
 
722
        json_value(const string_t& value)
 
723
        {
 
724
            string = create<string_t>(value);
 
725
        }
 
726
 
 
727
        /// constructor for objects
 
728
        json_value(const object_t& value)
 
729
        {
 
730
            object = create<object_t>(value);
 
731
        }
 
732
 
 
733
        /// constructor for arrays
 
734
        json_value(const array_t& value)
 
735
        {
 
736
            array = create<array_t>(value);
 
737
        }
 
738
    };
 
739
 
 
740
 
 
741
  public:
 
742
    //////////////////////////
 
743
    // JSON parser callback //
 
744
    //////////////////////////
 
745
 
 
746
    /*!
 
747
    @brief JSON callback events
 
748
 
 
749
    This enumeration lists the parser events that can trigger calling a
 
750
    callback function of type @ref parser_callback_t during parsing.
 
751
 
 
752
    @since version 1.0.0
 
753
    */
 
754
    enum class parse_event_t : uint8_t
 
755
    {
 
756
        /// the parser read `{` and started to process a JSON object
 
757
        object_start,
 
758
        /// the parser read `}` and finished processing a JSON object
 
759
        object_end,
 
760
        /// the parser read `[` and started to process a JSON array
 
761
        array_start,
 
762
        /// the parser read `]` and finished processing a JSON array
 
763
        array_end,
 
764
        /// the parser read a key of a value in an object
 
765
        key,
 
766
        /// the parser finished reading a JSON value
 
767
        value
 
768
    };
 
769
 
 
770
    /*!
 
771
    @brief per-element parser callback type
 
772
 
 
773
    With a parser callback function, the result of parsing a JSON text can be
 
774
    influenced. When passed to @ref parse(std::istream&, parser_callback_t) or
 
775
    @ref parse(const string_t&, parser_callback_t), it is called on certain
 
776
    events (passed as @ref parse_event_t via parameter @a event) with a set
 
777
    recursion depth @a depth and context JSON value @a parsed. The return value
 
778
    of the callback function is a boolean indicating whether the element that
 
779
    emitted the callback shall be kept or not.
 
780
 
 
781
    We distinguish six scenarios (determined by the event type) in which the
 
782
    callback function can be called. The following table describes the values
 
783
    of the parameters @a depth, @a event, and @a parsed.
 
784
 
 
785
    parameter @a event | description | parameter @a depth | parameter @a parsed
 
786
    ------------------ | ----------- | ------------------ | -------------------
 
787
    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
 
788
    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
 
789
    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
 
790
    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
 
791
    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
 
792
    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
 
793
 
 
794
    Discarding a value (i.e., returning `false`) has different effects
 
795
    depending on the context in which function was called:
 
796
 
 
797
    - Discarded values in structured types are skipped. That is, the parser
 
798
      will behave as if the discarded value was never read.
 
799
    - In case a value outside a structured type is skipped, it is replaced with
 
800
      `null`. This case happens if the top-level element is skipped.
 
801
 
 
802
    @param[in] depth  the depth of the recursion during parsing
 
803
 
 
804
    @param[in] event  an event of type parse_event_t indicating the context in
 
805
    the callback function has been called
 
806
 
 
807
    @param[in,out] parsed  the current intermediate parse result; note that
 
808
    writing to this value has no effect for parse_event_t::key events
 
809
 
 
810
    @return Whether the JSON value which called the function during parsing
 
811
    should be kept (`true`) or not (`false`). In the latter case, it is either
 
812
    skipped completely or replaced by an empty discarded object.
 
813
 
 
814
    @sa @ref parse(std::istream&, parser_callback_t) or
 
815
    @ref parse(const string_t&, parser_callback_t) for examples
 
816
 
 
817
    @since version 1.0.0
 
818
    */
 
819
    using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
 
820
 
 
821
 
 
822
    //////////////////
 
823
    // constructors //
 
824
    //////////////////
 
825
 
 
826
    /// @name constructors and destructors
 
827
    /// @{
 
828
 
 
829
    /*!
 
830
    @brief create an empty value with a given type
 
831
 
 
832
    Create an empty JSON value with a given type. The value will be default
 
833
    initialized with an empty value which depends on the type:
 
834
 
 
835
    Value type  | initial value
 
836
    ----------- | -------------
 
837
    null        | `null`
 
838
    boolean     | `false`
 
839
    string      | `""`
 
840
    number      | `0`
 
841
    object      | `{}`
 
842
    array       | `[]`
 
843
 
 
844
    @param[in] value_type  the type of the value to create
 
845
 
 
846
    @complexity Constant.
 
847
 
 
848
    @throw std::bad_alloc if allocation for object, array, or string value
 
849
    fails
 
850
 
 
851
    @liveexample{The following code shows the constructor for different @ref
 
852
    value_t values,basic_json__value_t}
 
853
 
 
854
    @sa @ref basic_json(std::nullptr_t) -- create a `null` value
 
855
    @sa @ref basic_json(boolean_t value) -- create a boolean value
 
856
    @sa @ref basic_json(const string_t&) -- create a string value
 
857
    @sa @ref basic_json(const object_t&) -- create a object value
 
858
    @sa @ref basic_json(const array_t&) -- create a array value
 
859
    @sa @ref basic_json(const number_float_t) -- create a number
 
860
    (floating-point) value
 
861
    @sa @ref basic_json(const number_integer_t) -- create a number (integer)
 
862
    value
 
863
 
 
864
    @since version 1.0.0
 
865
    */
 
866
    basic_json(const value_t value_type)
 
867
        : m_type(value_type), m_value(value_type)
 
868
    {}
 
869
 
 
870
    /*!
 
871
    @brief create a null object (implicitly)
 
872
 
 
873
    Create a `null` JSON value. This is the implicit version of the `null`
 
874
    value constructor as it takes no parameters.
 
875
 
 
876
    @complexity Constant.
 
877
 
 
878
    @requirement This function satisfies the Container requirements:
 
879
    - The complexity is constant.
 
880
    - As postcondition, it holds: `basic_json().empty() == true`.
 
881
 
 
882
    @liveexample{The following code shows the constructor for a `null` JSON
 
883
    value.,basic_json}
 
884
 
 
885
    @sa @ref basic_json(std::nullptr_t) -- create a `null` value
 
886
 
 
887
    @since version 1.0.0
 
888
    */
 
889
    basic_json() noexcept = default;
 
890
 
 
891
    /*!
 
892
    @brief create a null object (explicitly)
 
893
 
 
894
    Create a `null` JSON value. This is the explicitly version of the `null`
 
895
    value constructor as it takes a null pointer as parameter. It allows to
 
896
    create `null` values by explicitly assigning a @c nullptr to a JSON value.
 
897
    The passed null pointer itself is not read -- it is only used to choose the
 
898
    right constructor.
 
899
 
 
900
    @complexity Constant.
 
901
 
 
902
    @liveexample{The following code shows the constructor with null pointer
 
903
    parameter.,basic_json__nullptr_t}
 
904
 
 
905
    @sa @ref basic_json() -- default constructor (implicitly creating a `null`
 
906
    value)
 
907
 
 
908
    @since version 1.0.0
 
909
    */
 
910
    basic_json(std::nullptr_t) noexcept
 
911
        : basic_json(value_t::null)
 
912
    {}
 
913
 
 
914
    /*!
 
915
    @brief create an object (explicit)
 
916
 
 
917
    Create an object JSON value with a given content.
 
918
 
 
919
    @param[in] val  a value for the object
 
920
 
 
921
    @complexity Linear in the size of the passed @a val.
 
922
 
 
923
    @throw std::bad_alloc if allocation for object value fails
 
924
 
 
925
    @liveexample{The following code shows the constructor with an @ref object_t
 
926
    parameter.,basic_json__object_t}
 
927
 
 
928
    @sa @ref basic_json(const CompatibleObjectType&) -- create an object value
 
929
    from a compatible STL container
 
930
 
 
931
    @since version 1.0.0
 
932
    */
 
933
    basic_json(const object_t& val)
 
934
        : m_type(value_t::object), m_value(val)
 
935
    {}
 
936
 
 
937
    /*!
 
938
    @brief create an object (implicit)
 
939
 
 
940
    Create an object JSON value with a given content. This constructor allows
 
941
    any type that can be used to construct values of type @ref object_t.
 
942
    Examples include the types `std::map` and `std::unordered_map`.
 
943
 
 
944
    @tparam CompatibleObjectType an object type whose `key_type` and
 
945
    `value_type` is compatible to @ref object_t
 
946
 
 
947
    @param[in] val  a value for the object
 
948
 
 
949
    @complexity Linear in the size of the passed @a val.
 
950
 
 
951
    @throw std::bad_alloc if allocation for object value fails
 
952
 
 
953
    @liveexample{The following code shows the constructor with several
 
954
    compatible object type parameters.,basic_json__CompatibleObjectType}
 
955
 
 
956
    @sa @ref basic_json(const object_t&) -- create an object value
 
957
 
 
958
    @since version 1.0.0
 
959
    */
 
960
    template <class CompatibleObjectType, typename
 
961
              std::enable_if<
 
962
                  std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
 
963
                  std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type
 
964
              = 0>
 
965
    basic_json(const CompatibleObjectType& val)
 
966
        : m_type(value_t::object)
 
967
    {
 
968
        using std::begin;
 
969
        using std::end;
 
970
        m_value.object = create<object_t>(begin(val), end(val));
 
971
    }
 
972
 
 
973
    /*!
 
974
    @brief create an array (explicit)
 
975
 
 
976
    Create an array JSON value with a given content.
 
977
 
 
978
    @param[in] val  a value for the array
 
979
 
 
980
    @complexity Linear in the size of the passed @a val.
 
981
 
 
982
    @throw std::bad_alloc if allocation for array value fails
 
983
 
 
984
    @liveexample{The following code shows the constructor with an @ref array_t
 
985
    parameter.,basic_json__array_t}
 
986
 
 
987
    @sa @ref basic_json(const CompatibleArrayType&) -- create an array value
 
988
    from a compatible STL containers
 
989
 
 
990
    @since version 1.0.0
 
991
    */
 
992
    basic_json(const array_t& val)
 
993
        : m_type(value_t::array), m_value(val)
 
994
    {}
 
995
 
 
996
    /*!
 
997
    @brief create an array (implicit)
 
998
 
 
999
    Create an array JSON value with a given content. This constructor allows
 
1000
    any type that can be used to construct values of type @ref array_t.
 
1001
    Examples include the types `std::vector`, `std::list`, and `std::set`.
 
1002
 
 
1003
    @tparam CompatibleArrayType an object type whose `value_type` is compatible
 
1004
    to @ref array_t
 
1005
 
 
1006
    @param[in] val  a value for the array
 
1007
 
 
1008
    @complexity Linear in the size of the passed @a val.
 
1009
 
 
1010
    @throw std::bad_alloc if allocation for array value fails
 
1011
 
 
1012
    @liveexample{The following code shows the constructor with several
 
1013
    compatible array type parameters.,basic_json__CompatibleArrayType}
 
1014
 
 
1015
    @sa @ref basic_json(const array_t&) -- create an array value
 
1016
 
 
1017
    @since version 1.0.0
 
1018
    */
 
1019
    template <class CompatibleArrayType, typename
 
1020
              std::enable_if<
 
1021
                  not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
 
1022
                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
 
1023
                  not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
 
1024
                  not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
 
1025
                  not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
 
1026
                  not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
 
1027
                  std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type
 
1028
              = 0>
 
1029
    basic_json(const CompatibleArrayType& val)
 
1030
        : m_type(value_t::array)
 
1031
    {
 
1032
        using std::begin;
 
1033
        using std::end;
 
1034
        m_value.array = create<array_t>(begin(val), end(val));
 
1035
    }
 
1036
 
 
1037
    /*!
 
1038
    @brief create a string (explicit)
 
1039
 
 
1040
    Create an string JSON value with a given content.
 
1041
 
 
1042
    @param[in] val  a value for the string
 
1043
 
 
1044
    @complexity Linear in the size of the passed @a val.
 
1045
 
 
1046
    @throw std::bad_alloc if allocation for string value fails
 
1047
 
 
1048
    @liveexample{The following code shows the constructor with an @ref string_t
 
1049
    parameter.,basic_json__string_t}
 
1050
 
 
1051
    @sa @ref basic_json(const typename string_t::value_type*) -- create a
 
1052
    string value from a character pointer
 
1053
    @sa @ref basic_json(const CompatibleStringType&) -- create a string value
 
1054
    from a compatible string container
 
1055
 
 
1056
    @since version 1.0.0
 
1057
    */
 
1058
    basic_json(const string_t& val)
 
1059
        : m_type(value_t::string), m_value(val)
 
1060
    {}
 
1061
 
 
1062
    /*!
 
1063
    @brief create a string (explicit)
 
1064
 
 
1065
    Create a string JSON value with a given content.
 
1066
 
 
1067
    @param[in] val  a literal value for the string
 
1068
 
 
1069
    @complexity Linear in the size of the passed @a val.
 
1070
 
 
1071
    @throw std::bad_alloc if allocation for string value fails
 
1072
 
 
1073
    @liveexample{The following code shows the constructor with string literal
 
1074
    parameter.,basic_json__string_t_value_type}
 
1075
 
 
1076
    @sa @ref basic_json(const string_t&) -- create a string value
 
1077
    @sa @ref basic_json(const CompatibleStringType&) -- create a string value
 
1078
    from a compatible string container
 
1079
 
 
1080
    @since version 1.0.0
 
1081
    */
 
1082
    basic_json(const typename string_t::value_type* val)
 
1083
        : basic_json(string_t(val))
 
1084
    {}
 
1085
 
 
1086
    /*!
 
1087
    @brief create a string (implicit)
 
1088
 
 
1089
    Create a string JSON value with a given content.
 
1090
 
 
1091
    @param[in] val  a value for the string
 
1092
 
 
1093
    @tparam CompatibleStringType an string type which is compatible to @ref
 
1094
    string_t
 
1095
 
 
1096
    @complexity Linear in the size of the passed @a val.
 
1097
 
 
1098
    @throw std::bad_alloc if allocation for string value fails
 
1099
 
 
1100
    @liveexample{The following code shows the construction of a string value
 
1101
    from a compatible type.,basic_json__CompatibleStringType}
 
1102
 
 
1103
    @sa @ref basic_json(const string_t&) -- create a string value
 
1104
    @sa @ref basic_json(const typename string_t::value_type*) -- create a
 
1105
    string value from a character pointer
 
1106
 
 
1107
    @since version 1.0.0
 
1108
    */
 
1109
    template <class CompatibleStringType, typename
 
1110
              std::enable_if<
 
1111
                  std::is_constructible<string_t, CompatibleStringType>::value, int>::type
 
1112
              = 0>
 
1113
    basic_json(const CompatibleStringType& val)
 
1114
        : basic_json(string_t(val))
 
1115
    {}
 
1116
 
 
1117
    /*!
 
1118
    @brief create a boolean (explicit)
 
1119
 
 
1120
    Creates a JSON boolean type from a given value.
 
1121
 
 
1122
    @param[in] val  a boolean value to store
 
1123
 
 
1124
    @complexity Constant.
 
1125
 
 
1126
    @liveexample{The example below demonstrates boolean
 
1127
    values.,basic_json__boolean_t}
 
1128
 
 
1129
    @since version 1.0.0
 
1130
    */
 
1131
    basic_json(boolean_t val)
 
1132
        : m_type(value_t::boolean), m_value(val)
 
1133
    {}
 
1134
 
 
1135
    /*!
 
1136
    @brief create an integer number (explicit)
 
1137
 
 
1138
    Create an interger number JSON value with a given content.
 
1139
 
 
1140
    @tparam T  helper type to compare number_integer_t and int (not visible in)
 
1141
    the interface.
 
1142
 
 
1143
    @param[in] val  an integer to create a JSON number from
 
1144
 
 
1145
    @note This constructor would have the same signature as @ref
 
1146
    basic_json(const int value), so we need to switch this one off in case
 
1147
    number_integer_t is the same as int. This is done via the helper type @a T.
 
1148
 
 
1149
    @complexity Constant.
 
1150
 
 
1151
    @liveexample{The example below shows the construction of a JSON integer
 
1152
    number value.,basic_json__number_integer_t}
 
1153
 
 
1154
    @sa @ref basic_json(const int) -- create a number value (integer)
 
1155
    @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number
 
1156
    value (integer) from a compatible number type
 
1157
 
 
1158
    @since version 1.0.0
 
1159
    */
 
1160
    template<typename T,
 
1161
             typename std::enable_if<
 
1162
                 not (std::is_same<T, int>::value)
 
1163
                 and std::is_same<T, number_integer_t>::value
 
1164
                 , int>::type = 0>
 
1165
    basic_json(const number_integer_t val)
 
1166
        : m_type(value_t::number_integer), m_value(val)
 
1167
    {}
 
1168
 
 
1169
    /*!
 
1170
    @brief create an integer number from an enum type (explicit)
 
1171
 
 
1172
    Create an integer number JSON value with a given content.
 
1173
 
 
1174
    @param[in] val  an integer to create a JSON number from
 
1175
 
 
1176
    @note This constructor allows to pass enums directly to a constructor. As
 
1177
    C++ has no way of specifying the type of an anonymous enum explicitly, we
 
1178
    can only rely on the fact that such values implicitly convert to int. As
 
1179
    int may already be the same type of number_integer_t, we may need to switch
 
1180
    off the constructor @ref basic_json(const number_integer_t).
 
1181
 
 
1182
    @complexity Constant.
 
1183
 
 
1184
    @liveexample{The example below shows the construction of a JSON integer
 
1185
    number value from an anonymous enum.,basic_json__const_int}
 
1186
 
 
1187
    @sa @ref basic_json(const number_integer_t) -- create a number value
 
1188
    (integer)
 
1189
    @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number
 
1190
    value (integer) from a compatible number type
 
1191
 
 
1192
    @since version 1.0.0
 
1193
    */
 
1194
    basic_json(const int val)
 
1195
        : m_type(value_t::number_integer),
 
1196
          m_value(static_cast<number_integer_t>(val))
 
1197
    {}
 
1198
 
 
1199
    /*!
 
1200
    @brief create an integer number (implicit)
 
1201
 
 
1202
    Create an integer number JSON value with a given content. This constructor
 
1203
    allows any type that can be used to construct values of type @ref
 
1204
    number_integer_t. Examples may include the types `int`, `int32_t`, or
 
1205
    `short`.
 
1206
 
 
1207
    @tparam CompatibleNumberIntegerType an integer type which is compatible to
 
1208
    @ref number_integer_t.
 
1209
 
 
1210
    @param[in] val  an integer to create a JSON number from
 
1211
 
 
1212
    @complexity Constant.
 
1213
 
 
1214
    @liveexample{The example below shows the construction of several JSON
 
1215
    integer number values from compatible
 
1216
    types.,basic_json__CompatibleIntegerNumberType}
 
1217
 
 
1218
    @sa @ref basic_json(const number_integer_t) -- create a number value
 
1219
    (integer)
 
1220
    @sa @ref basic_json(const int) -- create a number value (integer)
 
1221
 
 
1222
    @since version 1.0.0
 
1223
    */
 
1224
    template<typename CompatibleNumberIntegerType, typename
 
1225
             std::enable_if<
 
1226
                 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
 
1227
                 std::numeric_limits<CompatibleNumberIntegerType>::is_integer, CompatibleNumberIntegerType>::type
 
1228
             = 0>
 
1229
    basic_json(const CompatibleNumberIntegerType val) noexcept
 
1230
        : m_type(value_t::number_integer),
 
1231
          m_value(static_cast<number_integer_t>(val))
 
1232
    {}
 
1233
 
 
1234
    /*!
 
1235
    @brief create a floating-point number (explicit)
 
1236
 
 
1237
    Create a floating-point number JSON value with a given content.
 
1238
 
 
1239
    @param[in] val  a floating-point value to create a JSON number from
 
1240
 
 
1241
    @note RFC 7159 <http://www.rfc-editor.org/rfc/rfc7159.txt>, section 6
 
1242
    disallows NaN values:
 
1243
    > Numeric values that cannot be represented in the grammar below (such
 
1244
    > as Infinity and NaN) are not permitted.
 
1245
    In case the parameter @a val is not a number, a JSON null value is
 
1246
    created instead.
 
1247
 
 
1248
    @complexity Constant.
 
1249
 
 
1250
    @liveexample{The following example creates several floating-point
 
1251
    values.,basic_json__number_float_t}
 
1252
 
 
1253
    @sa @ref basic_json(const CompatibleNumberFloatType) -- create a number
 
1254
    value (floating-point) from a compatible number type
 
1255
 
 
1256
    @since version 1.0.0
 
1257
    */
 
1258
    basic_json(const number_float_t val)
 
1259
        : m_type(value_t::number_float), m_value(val)
 
1260
    {
 
1261
        // replace infinity and NAN by null
 
1262
        if (not std::isfinite(val))
 
1263
        {
 
1264
            m_type = value_t::null;
 
1265
            m_value = json_value();
 
1266
        }
 
1267
    }
 
1268
 
 
1269
    /*!
 
1270
    @brief create an floating-point number (implicit)
 
1271
 
 
1272
    Create an floating-point number JSON value with a given content. This
 
1273
    constructor allows any type that can be used to construct values of type
 
1274
    @ref number_float_t. Examples may include the types `float`.
 
1275
 
 
1276
    @tparam CompatibleNumberFloatType a floating-point type which is compatible
 
1277
    to @ref number_float_t.
 
1278
 
 
1279
    @param[in] val  a floating-point to create a JSON number from
 
1280
 
 
1281
    @note RFC 7159 <http://www.rfc-editor.org/rfc/rfc7159.txt>, section 6
 
1282
    disallows NaN values:
 
1283
    > Numeric values that cannot be represented in the grammar below (such
 
1284
    > as Infinity and NaN) are not permitted.
 
1285
    In case the parameter @a val is not a number, a JSON null value is
 
1286
    created instead.
 
1287
 
 
1288
    @complexity Constant.
 
1289
 
 
1290
    @liveexample{The example below shows the construction of several JSON
 
1291
    floating-point number values from compatible
 
1292
    types.,basic_json__CompatibleNumberFloatType}
 
1293
 
 
1294
    @sa @ref basic_json(const number_float_t) -- create a number value
 
1295
    (floating-point)
 
1296
 
 
1297
    @since version 1.0.0
 
1298
    */
 
1299
    template<typename CompatibleNumberFloatType, typename = typename
 
1300
             std::enable_if<
 
1301
                 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
 
1302
                 std::is_floating_point<CompatibleNumberFloatType>::value>::type
 
1303
             >
 
1304
    basic_json(const CompatibleNumberFloatType val) noexcept
 
1305
        : basic_json(number_float_t(val))
 
1306
    {}
 
1307
 
 
1308
    /*!
 
1309
    @brief create a container (array or object) from an initializer list
 
1310
 
 
1311
    Creates a JSON value of type array or object from the passed initializer
 
1312
    list @a init. In case @a type_deduction is `true` (default), the type of
 
1313
    the JSON value to be created is deducted from the initializer list @a init
 
1314
    according to the following rules:
 
1315
 
 
1316
    1. If the list is empty, an empty JSON object value `{}` is created.
 
1317
    2. If the list consists of pairs whose first element is a string, a JSON
 
1318
    object value is created where the first elements of the pairs are treated
 
1319
    as keys and the second elements are as values.
 
1320
    3. In all other cases, an array is created.
 
1321
 
 
1322
    The rules aim to create the best fit between a C++ initializer list and
 
1323
    JSON values. The ratioinale is as follows:
 
1324
 
 
1325
    1. The empty initializer list is written as `{}` which is exactly an empty
 
1326
    JSON object.
 
1327
    2. C++ has now way of describing mapped types other than to list a list of
 
1328
    pairs. As JSON requires that keys must be of type string, rule 2 is the
 
1329
    weakest constraint one can pose on initializer lists to interpret them as
 
1330
    an object.
 
1331
    3. In all other cases, the initializer list could not be interpreted as
 
1332
    JSON object type, so interpreting it as JSON array type is safe.
 
1333
 
 
1334
    With the rules described above, the following JSON values cannot be
 
1335
    expressed by an initializer list:
 
1336
 
 
1337
    - the empty array (`[]`): use @ref array(std::initializer_list<basic_json>)
 
1338
      with an empty initializer list in this case
 
1339
    - arrays whose elements satisfy rule 2: use @ref
 
1340
      array(std::initializer_list<basic_json>) with the same initializer list
 
1341
      in this case
 
1342
 
 
1343
    @note When used without parentheses around an empty initializer list, @ref
 
1344
    basic_json() is called instead of this function, yielding the JSON null
 
1345
    value.
 
1346
 
 
1347
    @param[in] init  initializer list with JSON values
 
1348
 
 
1349
    @param[in] type_deduction internal parameter; when set to `true`, the type
 
1350
    of the JSON value is deducted from the initializer list @a init; when set
 
1351
    to `false`, the type provided via @a manual_type is forced. This mode is
 
1352
    used by the functions @ref array(std::initializer_list<basic_json>) and
 
1353
    @ref object(std::initializer_list<basic_json>).
 
1354
 
 
1355
    @param[in] manual_type internal parameter; when @a type_deduction is set to
 
1356
    `false`, the created JSON value will use the provided type (only @ref
 
1357
    value_t::array and @ref value_t::object are valid); when @a type_deduction
 
1358
    is set to `true`, this parameter has no effect
 
1359
 
 
1360
    @throw std::domain_error if @a type_deduction is `false`, @a manual_type is
 
1361
    `value_t::object`, but @a init contains an element which is not a pair
 
1362
    whose first element is a string; example: `"cannot create object from
 
1363
    initializer list"`
 
1364
 
 
1365
    @complexity Linear in the size of the initializer list @a init.
 
1366
 
 
1367
    @liveexample{The example below shows how JSON values are created from
 
1368
    initializer lists,basic_json__list_init_t}
 
1369
 
 
1370
    @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
 
1371
    value from an initializer list
 
1372
    @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
 
1373
    value from an initializer list
 
1374
 
 
1375
    @since version 1.0.0
 
1376
    */
 
1377
    basic_json(std::initializer_list<basic_json> init,
 
1378
               bool type_deduction = true,
 
1379
               value_t manual_type = value_t::array)
 
1380
    {
 
1381
        // the initializer list could describe an object
 
1382
        bool is_an_object = true;
 
1383
 
 
1384
        // check if each element is an array with two elements whose first
 
1385
        // element is a string
 
1386
        for (const auto& element : init)
 
1387
        {
 
1388
            if (not element.is_array() or element.size() != 2
 
1389
                    or not element[0].is_string())
 
1390
            {
 
1391
                // we found an element that makes it impossible to use the
 
1392
                // initializer list as object
 
1393
                is_an_object = false;
 
1394
                break;
 
1395
            }
 
1396
        }
 
1397
 
 
1398
        // adjust type if type deduction is not wanted
 
1399
        if (not type_deduction)
 
1400
        {
 
1401
            // if array is wanted, do not create an object though possible
 
1402
            if (manual_type == value_t::array)
 
1403
            {
 
1404
                is_an_object = false;
 
1405
            }
 
1406
 
 
1407
            // if object is wanted but impossible, throw an exception
 
1408
            if (manual_type == value_t::object and not is_an_object)
 
1409
            {
 
1410
                throw std::domain_error("cannot create object from initializer list");
 
1411
            }
 
1412
        }
 
1413
 
 
1414
        if (is_an_object)
 
1415
        {
 
1416
            // the initializer list is a list of pairs -> create object
 
1417
            m_type = value_t::object;
 
1418
            m_value = value_t::object;
 
1419
 
 
1420
            for (auto& element : init)
 
1421
            {
 
1422
                m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
 
1423
            }
 
1424
        }
 
1425
        else
 
1426
        {
 
1427
            // the initializer list describes an array -> create array
 
1428
            m_type = value_t::array;
 
1429
            m_value.array = create<array_t>(std::move(init));
 
1430
        }
 
1431
    }
 
1432
 
 
1433
    /*!
 
1434
    @brief explicitly create an array from an initializer list
 
1435
 
 
1436
    Creates a JSON array value from a given initializer list. That is, given a
 
1437
    list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
 
1438
    initializer list is empty, the empty array `[]` is created.
 
1439
 
 
1440
    @note This function is only needed to express two edge cases that cannot be
 
1441
    realized with the initializer list constructor (@ref
 
1442
    basic_json(std::initializer_list<basic_json>, bool, value_t)). These cases
 
1443
    are:
 
1444
    1. creating an array whose elements are all pairs whose first element is a
 
1445
    string -- in this case, the initializer list constructor would create an
 
1446
    object, taking the first elements as keys
 
1447
    2. creating an empty array -- passing the empty initializer list to the
 
1448
    initializer list constructor yields an empty object
 
1449
 
 
1450
    @param[in] init  initializer list with JSON values to create an array from
 
1451
    (optional)
 
1452
 
 
1453
    @return JSON array value
 
1454
 
 
1455
    @complexity Linear in the size of @a init.
 
1456
 
 
1457
    @liveexample{The following code shows an example for the @ref array
 
1458
    function.,array}
 
1459
 
 
1460
    @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
 
1461
    create a JSON value from an initializer list
 
1462
    @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
 
1463
    value from an initializer list
 
1464
 
 
1465
    @since version 1.0.0
 
1466
    */
 
1467
    static basic_json array(std::initializer_list<basic_json> init =
 
1468
                                std::initializer_list<basic_json>())
 
1469
    {
 
1470
        return basic_json(init, false, value_t::array);
 
1471
    }
 
1472
 
 
1473
    /*!
 
1474
    @brief explicitly create an object from an initializer list
 
1475
 
 
1476
    Creates a JSON object value from a given initializer list. The initializer
 
1477
    lists elements must be pairs, and their first elments must be strings. If
 
1478
    the initializer list is empty, the empty object `{}` is created.
 
1479
 
 
1480
    @note This function is only added for symmetry reasons. In contrast to the
 
1481
    related function @ref array(std::initializer_list<basic_json>), there are
 
1482
    no cases which can only be expressed by this function. That is, any
 
1483
    initializer list @a init can also be passed to the initializer list
 
1484
    constructor
 
1485
    @ref basic_json(std::initializer_list<basic_json>, bool, value_t).
 
1486
 
 
1487
    @param[in] init  initializer list to create an object from (optional)
 
1488
 
 
1489
    @return JSON object value
 
1490
 
 
1491
    @throw std::domain_error if @a init is not a pair whose first elements are
 
1492
    strings; thrown by
 
1493
    @ref basic_json(std::initializer_list<basic_json>, bool, value_t)
 
1494
 
 
1495
    @complexity Linear in the size of @a init.
 
1496
 
 
1497
    @liveexample{The following code shows an example for the @ref object
 
1498
    function.,object}
 
1499
 
 
1500
    @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
 
1501
    create a JSON value from an initializer list
 
1502
    @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
 
1503
    value from an initializer list
 
1504
 
 
1505
    @since version 1.0.0
 
1506
    */
 
1507
    static basic_json object(std::initializer_list<basic_json> init =
 
1508
                                 std::initializer_list<basic_json>())
 
1509
    {
 
1510
        return basic_json(init, false, value_t::object);
 
1511
    }
 
1512
 
 
1513
    /*!
 
1514
    @brief construct an array with count copies of given value
 
1515
 
 
1516
    Constructs a JSON array value by creating @a cnt copies of a passed
 
1517
    value. In case @a cnt is `0`, an empty array is created. As postcondition,
 
1518
    `std::distance(begin(),end()) == cnt` holds.
 
1519
 
 
1520
    @param[in] cnt  the number of JSON copies of @a val to create
 
1521
    @param[in] val  the JSON value to copy
 
1522
 
 
1523
    @complexity Linear in @a cnt.
 
1524
 
 
1525
    @liveexample{The following code shows examples for the @ref
 
1526
    basic_json(size_type\, const basic_json&)
 
1527
    constructor.,basic_json__size_type_basic_json}
 
1528
 
 
1529
    @since version 1.0.0
 
1530
    */
 
1531
    basic_json(size_type cnt, const basic_json& val)
 
1532
        : m_type(value_t::array)
 
1533
    {
 
1534
        m_value.array = create<array_t>(cnt, val);
 
1535
    }
 
1536
 
 
1537
    /*!
 
1538
    @brief construct a JSON container given an iterator range
 
1539
 
 
1540
    Constructs the JSON value with the contents of the range `[first, last)`.
 
1541
    The semantics depends on the different types a JSON value can have:
 
1542
    - In case of primitive types (number, boolean, or string), @a first must
 
1543
      be `begin()` and @a last must be `end()`. In this case, the value is
 
1544
      copied. Otherwise, std::out_of_range is thrown.
 
1545
    - In case of structured types (array, object), the constructor behaves
 
1546
      as similar versions for `std::vector`.
 
1547
    - In case of a null type, std::domain_error is thrown.
 
1548
 
 
1549
    @tparam InputIT an input iterator type (@ref iterator or @ref
 
1550
    const_iterator)
 
1551
 
 
1552
    @param[in] first begin of the range to copy from (included)
 
1553
    @param[in] last end of the range to copy from (excluded)
 
1554
 
 
1555
    @throw std::domain_error if iterators are not compatible; that is, do not
 
1556
    belong to the same JSON value; example: `"iterators are not compatible"`
 
1557
    @throw std::out_of_range if iterators are for a primitive type (number,
 
1558
    boolean, or string) where an out of range error can be detected easily;
 
1559
    example: `"iterators out of range"`
 
1560
    @throw std::bad_alloc if allocation for object, array, or string fails
 
1561
    @throw std::domain_error if called with a null value; example: `"cannot use
 
1562
    construct with iterators from null"`
 
1563
 
 
1564
    @complexity Linear in distance between @a first and @a last.
 
1565
 
 
1566
    @liveexample{The example below shows several ways to create JSON values by
 
1567
    specifying a subrange with iterators.,basic_json__InputIt_InputIt}
 
1568
 
 
1569
    @since version 1.0.0
 
1570
    */
 
1571
    template <class InputIT, typename
 
1572
              std::enable_if<
 
1573
                  std::is_same<InputIT, typename basic_json_t::iterator>::value or
 
1574
                  std::is_same<InputIT, typename basic_json_t::const_iterator>::value
 
1575
                  , int>::type
 
1576
              = 0>
 
1577
    basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
 
1578
    {
 
1579
        // make sure iterator fits the current value
 
1580
        if (first.m_object != last.m_object)
 
1581
        {
 
1582
            throw std::domain_error("iterators are not compatible");
 
1583
        }
 
1584
 
 
1585
        // check if iterator range is complete for primitive values
 
1586
        switch (m_type)
 
1587
        {
 
1588
            case value_t::boolean:
 
1589
            case value_t::number_float:
 
1590
            case value_t::number_integer:
 
1591
            case value_t::string:
 
1592
            {
 
1593
                if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
 
1594
                {
 
1595
                    throw std::out_of_range("iterators out of range");
 
1596
                }
 
1597
                break;
 
1598
            }
 
1599
 
 
1600
            default:
 
1601
            {
 
1602
                break;
 
1603
            }
 
1604
        }
 
1605
 
 
1606
        switch (m_type)
 
1607
        {
 
1608
            case value_t::number_integer:
 
1609
            {
 
1610
                m_value.number_integer = first.m_object->m_value.number_integer;
 
1611
                break;
 
1612
            }
 
1613
 
 
1614
            case value_t::number_float:
 
1615
            {
 
1616
                m_value.number_float = first.m_object->m_value.number_float;
 
1617
                break;
 
1618
            }
 
1619
 
 
1620
            case value_t::boolean:
 
1621
            {
 
1622
                m_value.boolean = first.m_object->m_value.boolean;
 
1623
                break;
 
1624
            }
 
1625
 
 
1626
            case value_t::string:
 
1627
            {
 
1628
                m_value = *first.m_object->m_value.string;
 
1629
                break;
 
1630
            }
 
1631
 
 
1632
            case value_t::object:
 
1633
            {
 
1634
                m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
 
1635
                break;
 
1636
            }
 
1637
 
 
1638
            case value_t::array:
 
1639
            {
 
1640
                m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
 
1641
                break;
 
1642
            }
 
1643
 
 
1644
            default:
 
1645
            {
 
1646
                throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
 
1647
            }
 
1648
        }
 
1649
    }
 
1650
 
 
1651
    ///////////////////////////////////////
 
1652
    // other constructors and destructor //
 
1653
    ///////////////////////////////////////
 
1654
 
 
1655
    /*!
 
1656
    @brief copy constructor
 
1657
 
 
1658
    Creates a copy of a given JSON value.
 
1659
 
 
1660
    @param[in] other  the JSON value to copy
 
1661
 
 
1662
    @complexity Linear in the size of @a other.
 
1663
 
 
1664
    @requirement This function satisfies the Container requirements:
 
1665
    - The complexity is linear.
 
1666
    - As postcondition, it holds: `other == basic_json(other)`.
 
1667
 
 
1668
    @throw std::bad_alloc if allocation for object, array, or string fails.
 
1669
 
 
1670
    @liveexample{The following code shows an example for the copy
 
1671
    constructor.,basic_json__basic_json}
 
1672
 
 
1673
    @since version 1.0.0
 
1674
    */
 
1675
    basic_json(const basic_json& other)
 
1676
        : m_type(other.m_type)
 
1677
    {
 
1678
        switch (m_type)
 
1679
        {
 
1680
            case value_t::object:
 
1681
            {
 
1682
                m_value = *other.m_value.object;
 
1683
                break;
 
1684
            }
 
1685
 
 
1686
            case value_t::array:
 
1687
            {
 
1688
                m_value = *other.m_value.array;
 
1689
                break;
 
1690
            }
 
1691
 
 
1692
            case value_t::string:
 
1693
            {
 
1694
                m_value = *other.m_value.string;
 
1695
                break;
 
1696
            }
 
1697
 
 
1698
            case value_t::boolean:
 
1699
            {
 
1700
                m_value = other.m_value.boolean;
 
1701
                break;
 
1702
            }
 
1703
 
 
1704
            case value_t::number_integer:
 
1705
            {
 
1706
                m_value = other.m_value.number_integer;
 
1707
                break;
 
1708
            }
 
1709
 
 
1710
            case value_t::number_float:
 
1711
            {
 
1712
                m_value = other.m_value.number_float;
 
1713
                break;
 
1714
            }
 
1715
 
 
1716
            default:
 
1717
            {
 
1718
                break;
 
1719
            }
 
1720
        }
 
1721
    }
 
1722
 
 
1723
    /*!
 
1724
    @brief move constructor
 
1725
 
 
1726
    Move constructor. Constructs a JSON value with the contents of the given
 
1727
    value @a other using move semantics. It "steals" the resources from @a
 
1728
    other and leaves it as JSON null value.
 
1729
 
 
1730
    @param[in,out] other  value to move to this object
 
1731
 
 
1732
    @post @a other is a JSON null value
 
1733
 
 
1734
    @complexity Constant.
 
1735
 
 
1736
    @liveexample{The code below shows the move constructor explicitly called
 
1737
    via std::move.,basic_json__moveconstructor}
 
1738
 
 
1739
    @since version 1.0.0
 
1740
    */
 
1741
    basic_json(basic_json&& other) noexcept
 
1742
        : m_type(std::move(other.m_type)),
 
1743
          m_value(std::move(other.m_value))
 
1744
    {
 
1745
        // invalidate payload
 
1746
        other.m_type = value_t::null;
 
1747
        other.m_value = {};
 
1748
    }
 
1749
 
 
1750
    /*!
 
1751
    @brief copy assignment
 
1752
 
 
1753
    Copy assignment operator. Copies a JSON value via the "copy and swap"
 
1754
    strategy: It is expressed in terms of the copy constructor, destructor, and
 
1755
    the swap() member function.
 
1756
 
 
1757
    @param[in] other  value to copy from
 
1758
 
 
1759
    @complexity Linear.
 
1760
 
 
1761
    @requirement This function satisfies the Container requirements:
 
1762
    - The complexity is linear.
 
1763
 
 
1764
    @liveexample{The code below shows and example for the copy assignment. It
 
1765
    creates a copy of value `a` which is then swapped with `b`. Finally\, the
 
1766
    copy of `a` (which is the null value after the swap) is
 
1767
    destroyed.,basic_json__copyassignment}
 
1768
 
 
1769
    @since version 1.0.0
 
1770
    */
 
1771
    reference& operator=(basic_json other) noexcept (
 
1772
        std::is_nothrow_move_constructible<value_t>::value and
 
1773
        std::is_nothrow_move_assignable<value_t>::value and
 
1774
        std::is_nothrow_move_constructible<json_value>::value and
 
1775
        std::is_nothrow_move_assignable<json_value>::value
 
1776
    )
 
1777
    {
 
1778
        using std::swap;
 
1779
        swap(m_type, other.m_type);
 
1780
        swap(m_value, other.m_value);
 
1781
        return *this;
 
1782
    }
 
1783
 
 
1784
    /*!
 
1785
    @brief destructor
 
1786
 
 
1787
    Destroys the JSON value and frees all allocated memory.
 
1788
 
 
1789
    @complexity Linear.
 
1790
 
 
1791
    @requirement This function satisfies the Container requirements:
 
1792
    - The complexity is linear.
 
1793
    - All stored elements are destroyed and all memory is freed.
 
1794
 
 
1795
    @since version 1.0.0
 
1796
    */
 
1797
    ~basic_json()
 
1798
    {
 
1799
        switch (m_type)
 
1800
        {
 
1801
            case value_t::object:
 
1802
            {
 
1803
                AllocatorType<object_t> alloc;
 
1804
                alloc.destroy(m_value.object);
 
1805
                alloc.deallocate(m_value.object, 1);
 
1806
                break;
 
1807
            }
 
1808
 
 
1809
            case value_t::array:
 
1810
            {
 
1811
                AllocatorType<array_t> alloc;
 
1812
                alloc.destroy(m_value.array);
 
1813
                alloc.deallocate(m_value.array, 1);
 
1814
                break;
 
1815
            }
 
1816
 
 
1817
            case value_t::string:
 
1818
            {
 
1819
                AllocatorType<string_t> alloc;
 
1820
                alloc.destroy(m_value.string);
 
1821
                alloc.deallocate(m_value.string, 1);
 
1822
                break;
 
1823
            }
 
1824
 
 
1825
            default:
 
1826
            {
 
1827
                // all other types need no specific destructor
 
1828
                break;
 
1829
            }
 
1830
        }
 
1831
    }
 
1832
 
 
1833
    /// @}
 
1834
 
 
1835
  public:
 
1836
    ///////////////////////
 
1837
    // object inspection //
 
1838
    ///////////////////////
 
1839
 
 
1840
    /// @name object inspection
 
1841
    /// @{
 
1842
 
 
1843
    /*!
 
1844
    @brief serialization
 
1845
 
 
1846
    Serialization function for JSON values. The function tries to mimick
 
1847
    Python's @p json.dumps() function, and currently supports its @p indent
 
1848
    parameter.
 
1849
 
 
1850
    @param[in] indent if indent is nonnegative, then array elements and object
 
1851
    members will be pretty-printed with that indent level. An indent level of 0
 
1852
    will only insert newlines. -1 (the default) selects the most compact
 
1853
    representation
 
1854
 
 
1855
    @return string containing the serialization of the JSON value
 
1856
 
 
1857
    @complexity Linear.
 
1858
 
 
1859
    @liveexample{The following example shows the effect of different @a indent
 
1860
    parameters to the result of the serializaion.,dump}
 
1861
 
 
1862
    @see https://docs.python.org/2/library/json.html#json.dump
 
1863
 
 
1864
    @since version 1.0.0
 
1865
    */
 
1866
    string_t dump(const int indent = -1) const
 
1867
    {
 
1868
        std::stringstream ss;
 
1869
 
 
1870
        if (indent >= 0)
 
1871
        {
 
1872
            dump(ss, true, static_cast<unsigned int>(indent));
 
1873
        }
 
1874
        else
 
1875
        {
 
1876
            dump(ss, false, 0);
 
1877
        }
 
1878
 
 
1879
        return ss.str();
 
1880
    }
 
1881
 
 
1882
    /*!
 
1883
    @brief return the type of the JSON value (explicit)
 
1884
 
 
1885
    Return the type of the JSON value as a value from the @ref value_t
 
1886
    enumeration.
 
1887
 
 
1888
    @return the type of the JSON value
 
1889
 
 
1890
    @complexity Constant.
 
1891
 
 
1892
    @liveexample{The following code exemplifies @ref type() for all JSON
 
1893
    types.,type}
 
1894
 
 
1895
    @since version 1.0.0
 
1896
    */
 
1897
    value_t type() const noexcept
 
1898
    {
 
1899
        return m_type;
 
1900
    }
 
1901
 
 
1902
    /*!
 
1903
    @brief return whether type is primitive
 
1904
 
 
1905
    This function returns true iff the JSON type is primitive (string, number,
 
1906
    boolean, or null).
 
1907
 
 
1908
    @return `true` if type is primitive (string, number, boolean, or null),
 
1909
    `false` otherwise.
 
1910
 
 
1911
    @complexity Constant.
 
1912
 
 
1913
    @liveexample{The following code exemplifies @ref is_primitive for all JSON
 
1914
    types.,is_primitive}
 
1915
 
 
1916
    @since version 1.0.0
 
1917
    */
 
1918
    bool is_primitive() const noexcept
 
1919
    {
 
1920
        return is_null() or is_string() or is_boolean() or is_number();
 
1921
    }
 
1922
 
 
1923
    /*!
 
1924
    @brief return whether type is structured
 
1925
 
 
1926
    This function returns true iff the JSON type is structured (array or
 
1927
    object).
 
1928
 
 
1929
    @return `true` if type is structured (array or object), `false` otherwise.
 
1930
 
 
1931
    @complexity Constant.
 
1932
 
 
1933
    @liveexample{The following code exemplifies @ref is_structured for all JSON
 
1934
    types.,is_structured}
 
1935
 
 
1936
    @since version 1.0.0
 
1937
    */
 
1938
    bool is_structured() const noexcept
 
1939
    {
 
1940
        return is_array() or is_object();
 
1941
    }
 
1942
 
 
1943
    /*!
 
1944
    @brief return whether value is null
 
1945
 
 
1946
    This function returns true iff the JSON value is null.
 
1947
 
 
1948
    @return `true` if type is null, `false` otherwise.
 
1949
 
 
1950
    @complexity Constant.
 
1951
 
 
1952
    @liveexample{The following code exemplifies @ref is_null for all JSON
 
1953
    types.,is_null}
 
1954
 
 
1955
    @since version 1.0.0
 
1956
    */
 
1957
    bool is_null() const noexcept
 
1958
    {
 
1959
        return m_type == value_t::null;
 
1960
    }
 
1961
 
 
1962
    /*!
 
1963
    @brief return whether value is a boolean
 
1964
 
 
1965
    This function returns true iff the JSON value is a boolean.
 
1966
 
 
1967
    @return `true` if type is boolean, `false` otherwise.
 
1968
 
 
1969
    @complexity Constant.
 
1970
 
 
1971
    @liveexample{The following code exemplifies @ref is_boolean for all JSON
 
1972
    types.,is_boolean}
 
1973
 
 
1974
    @since version 1.0.0
 
1975
    */
 
1976
    bool is_boolean() const noexcept
 
1977
    {
 
1978
        return m_type == value_t::boolean;
 
1979
    }
 
1980
 
 
1981
    /*!
 
1982
    @brief return whether value is a number
 
1983
 
 
1984
    This function returns true iff the JSON value is a number. This includes
 
1985
    both integer and floating-point values.
 
1986
 
 
1987
    @return `true` if type is number (regardless whether integer or
 
1988
    floating-type), `false` otherwise.
 
1989
 
 
1990
    @complexity Constant.
 
1991
 
 
1992
    @liveexample{The following code exemplifies @ref is_number for all JSON
 
1993
    types.,is_number}
 
1994
 
 
1995
    @sa @ref is_number_integer() -- check if value is an integer number
 
1996
    @sa @ref is_number_float() -- check if value is a floating-point number
 
1997
 
 
1998
    @since version 1.0.0
 
1999
    */
 
2000
    bool is_number() const noexcept
 
2001
    {
 
2002
        return is_number_integer() or is_number_float();
 
2003
    }
 
2004
 
 
2005
    /*!
 
2006
    @brief return whether value is an integer number
 
2007
 
 
2008
    This function returns true iff the JSON value is an integer number. This
 
2009
    excludes floating-point values.
 
2010
 
 
2011
    @return `true` if type is an integer number, `false` otherwise.
 
2012
 
 
2013
    @complexity Constant.
 
2014
 
 
2015
    @liveexample{The following code exemplifies @ref is_number_integer for all
 
2016
    JSON types.,is_number_integer}
 
2017
 
 
2018
    @sa @ref is_number() -- check if value is a number
 
2019
    @sa @ref is_number_float() -- check if value is a floating-point number
 
2020
 
 
2021
    @since version 1.0.0
 
2022
    */
 
2023
    bool is_number_integer() const noexcept
 
2024
    {
 
2025
        return m_type == value_t::number_integer;
 
2026
    }
 
2027
 
 
2028
    /*!
 
2029
    @brief return whether value is a floating-point number
 
2030
 
 
2031
    This function returns true iff the JSON value is a floating-point number.
 
2032
    This excludes integer values.
 
2033
 
 
2034
    @return `true` if type is a floating-point number, `false` otherwise.
 
2035
 
 
2036
    @complexity Constant.
 
2037
 
 
2038
    @liveexample{The following code exemplifies @ref is_number_float for all
 
2039
    JSON types.,is_number_float}
 
2040
 
 
2041
    @sa @ref is_number() -- check if value is number
 
2042
    @sa @ref is_number_integer() -- check if value is an integer number
 
2043
 
 
2044
    @since version 1.0.0
 
2045
    */
 
2046
    bool is_number_float() const noexcept
 
2047
    {
 
2048
        return m_type == value_t::number_float;
 
2049
    }
 
2050
 
 
2051
    /*!
 
2052
    @brief return whether value is an object
 
2053
 
 
2054
    This function returns true iff the JSON value is an object.
 
2055
 
 
2056
    @return `true` if type is object, `false` otherwise.
 
2057
 
 
2058
    @complexity Constant.
 
2059
 
 
2060
    @liveexample{The following code exemplifies @ref is_object for all JSON
 
2061
    types.,is_object}
 
2062
 
 
2063
    @since version 1.0.0
 
2064
    */
 
2065
    bool is_object() const noexcept
 
2066
    {
 
2067
        return m_type == value_t::object;
 
2068
    }
 
2069
 
 
2070
    /*!
 
2071
    @brief return whether value is an array
 
2072
 
 
2073
    This function returns true iff the JSON value is an array.
 
2074
 
 
2075
    @return `true` if type is array, `false` otherwise.
 
2076
 
 
2077
    @complexity Constant.
 
2078
 
 
2079
    @liveexample{The following code exemplifies @ref is_array for all JSON
 
2080
    types.,is_array}
 
2081
 
 
2082
    @since version 1.0.0
 
2083
    */
 
2084
    bool is_array() const noexcept
 
2085
    {
 
2086
        return m_type == value_t::array;
 
2087
    }
 
2088
 
 
2089
    /*!
 
2090
    @brief return whether value is a string
 
2091
 
 
2092
    This function returns true iff the JSON value is a string.
 
2093
 
 
2094
    @return `true` if type is string, `false` otherwise.
 
2095
 
 
2096
    @complexity Constant.
 
2097
 
 
2098
    @liveexample{The following code exemplifies @ref is_string for all JSON
 
2099
    types.,is_string}
 
2100
 
 
2101
    @since version 1.0.0
 
2102
    */
 
2103
    bool is_string() const noexcept
 
2104
    {
 
2105
        return m_type == value_t::string;
 
2106
    }
 
2107
 
 
2108
    /*!
 
2109
    @brief return whether value is discarded
 
2110
 
 
2111
    This function returns true iff the JSON value was discarded during parsing
 
2112
    with a callback function (see @ref parser_callback_t).
 
2113
 
 
2114
    @note This function will always be `false` for JSON values after parsing.
 
2115
    That is, discarded values can only occur during parsing, but will be
 
2116
    removed when inside a structured value or replaced by null in other cases.
 
2117
 
 
2118
    @return `true` if type is discarded, `false` otherwise.
 
2119
 
 
2120
    @complexity Constant.
 
2121
 
 
2122
    @liveexample{The following code exemplifies @ref is_discarded for all JSON
 
2123
    types.,is_discarded}
 
2124
 
 
2125
    @since version 1.0.0
 
2126
    */
 
2127
    bool is_discarded() const noexcept
 
2128
    {
 
2129
        return m_type == value_t::discarded;
 
2130
    }
 
2131
 
 
2132
    /*!
 
2133
    @brief return the type of the JSON value (implicit)
 
2134
 
 
2135
    Implicitly return the type of the JSON value as a value from the @ref
 
2136
    value_t enumeration.
 
2137
 
 
2138
    @return the type of the JSON value
 
2139
 
 
2140
    @complexity Constant.
 
2141
 
 
2142
    @liveexample{The following code exemplifies the value_t operator for all
 
2143
    JSON types.,operator__value_t}
 
2144
 
 
2145
    @since version 1.0.0
 
2146
    */
 
2147
    operator value_t() const noexcept
 
2148
    {
 
2149
        return m_type;
 
2150
    }
 
2151
 
 
2152
    /// @}
 
2153
 
 
2154
  private:
 
2155
    //////////////////
 
2156
    // value access //
 
2157
    //////////////////
 
2158
 
 
2159
    /// get an object (explicit)
 
2160
    template <class T, typename
 
2161
              std::enable_if<
 
2162
                  std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
 
2163
                  std::is_convertible<basic_json_t, typename T::mapped_type>::value
 
2164
                  , int>::type = 0>
 
2165
    T get_impl(T*) const
 
2166
    {
 
2167
        if (is_object())
 
2168
        {
 
2169
            return T(m_value.object->begin(), m_value.object->end());
 
2170
        }
 
2171
        else
 
2172
        {
 
2173
            throw std::domain_error("type must be object, but is " + type_name());
 
2174
        }
 
2175
    }
 
2176
 
 
2177
    /// get an object (explicit)
 
2178
    object_t get_impl(object_t*) const
 
2179
    {
 
2180
        if (is_object())
 
2181
        {
 
2182
            return *(m_value.object);
 
2183
        }
 
2184
        else
 
2185
        {
 
2186
            throw std::domain_error("type must be object, but is " + type_name());
 
2187
        }
 
2188
    }
 
2189
 
 
2190
    /// get an array (explicit)
 
2191
    template <class T, typename
 
2192
              std::enable_if<
 
2193
                  std::is_convertible<basic_json_t, typename T::value_type>::value and
 
2194
                  not std::is_same<basic_json_t, typename T::value_type>::value and
 
2195
                  not std::is_arithmetic<T>::value and
 
2196
                  not std::is_convertible<std::string, T>::value and
 
2197
                  not has_mapped_type<T>::value
 
2198
                  , int>::type = 0>
 
2199
    T get_impl(T*) const
 
2200
    {
 
2201
        if (is_array())
 
2202
        {
 
2203
            T to_vector;
 
2204
            std::transform(m_value.array->begin(), m_value.array->end(),
 
2205
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 
2206
            {
 
2207
                return i.get<typename T::value_type>();
 
2208
            });
 
2209
            return to_vector;
 
2210
        }
 
2211
        else
 
2212
        {
 
2213
            throw std::domain_error("type must be array, but is " + type_name());
 
2214
        }
 
2215
    }
 
2216
 
 
2217
    /// get an array (explicit)
 
2218
    template <class T, typename
 
2219
              std::enable_if<
 
2220
                  std::is_convertible<basic_json_t, T>::value and
 
2221
                  not std::is_same<basic_json_t, T>::value
 
2222
                  , int>::type = 0>
 
2223
    std::vector<T> get_impl(std::vector<T>*) const
 
2224
    {
 
2225
        if (is_array())
 
2226
        {
 
2227
            std::vector<T> to_vector;
 
2228
            to_vector.reserve(m_value.array->size());
 
2229
            std::transform(m_value.array->begin(), m_value.array->end(),
 
2230
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 
2231
            {
 
2232
                return i.get<T>();
 
2233
            });
 
2234
            return to_vector;
 
2235
        }
 
2236
        else
 
2237
        {
 
2238
            throw std::domain_error("type must be array, but is " + type_name());
 
2239
        }
 
2240
    }
 
2241
 
 
2242
    /// get an array (explicit)
 
2243
    template <class T, typename
 
2244
              std::enable_if<
 
2245
                  std::is_same<basic_json, typename T::value_type>::value and
 
2246
                  not has_mapped_type<T>::value
 
2247
                  , int>::type = 0>
 
2248
    T get_impl(T*) const
 
2249
    {
 
2250
        if (is_array())
 
2251
        {
 
2252
            return T(m_value.array->begin(), m_value.array->end());
 
2253
        }
 
2254
        else
 
2255
        {
 
2256
            throw std::domain_error("type must be array, but is " + type_name());
 
2257
        }
 
2258
    }
 
2259
 
 
2260
    /// get an array (explicit)
 
2261
    array_t get_impl(array_t*) const
 
2262
    {
 
2263
        if (is_array())
 
2264
        {
 
2265
            return *(m_value.array);
 
2266
        }
 
2267
        else
 
2268
        {
 
2269
            throw std::domain_error("type must be array, but is " + type_name());
 
2270
        }
 
2271
    }
 
2272
 
 
2273
    /// get a string (explicit)
 
2274
    template <typename T, typename
 
2275
              std::enable_if<
 
2276
                  std::is_convertible<string_t, T>::value
 
2277
                  , int>::type = 0>
 
2278
    T get_impl(T*) const
 
2279
    {
 
2280
        if (is_string())
 
2281
        {
 
2282
            return *m_value.string;
 
2283
        }
 
2284
        else
 
2285
        {
 
2286
            throw std::domain_error("type must be string, but is " + type_name());
 
2287
        }
 
2288
    }
 
2289
 
 
2290
    /// get a number (explicit)
 
2291
    template<typename T, typename
 
2292
             std::enable_if<
 
2293
                 std::is_arithmetic<T>::value
 
2294
                 , int>::type = 0>
 
2295
    T get_impl(T*) const
 
2296
    {
 
2297
        switch (m_type)
 
2298
        {
 
2299
            case value_t::number_integer:
 
2300
            {
 
2301
                return static_cast<T>(m_value.number_integer);
 
2302
            }
 
2303
 
 
2304
            case value_t::number_float:
 
2305
            {
 
2306
                return static_cast<T>(m_value.number_float);
 
2307
            }
 
2308
 
 
2309
            default:
 
2310
            {
 
2311
                throw std::domain_error("type must be number, but is " + type_name());
 
2312
            }
 
2313
        }
 
2314
    }
 
2315
 
 
2316
    /// get a boolean (explicit)
 
2317
    boolean_t get_impl(boolean_t*) const
 
2318
    {
 
2319
        if (is_boolean())
 
2320
        {
 
2321
            return m_value.boolean;
 
2322
        }
 
2323
        else
 
2324
        {
 
2325
            throw std::domain_error("type must be boolean, but is " + type_name());
 
2326
        }
 
2327
    }
 
2328
 
 
2329
    /// get a pointer to the value (object)
 
2330
    object_t* get_impl_ptr(object_t*) noexcept
 
2331
    {
 
2332
        return is_object() ? m_value.object : nullptr;
 
2333
    }
 
2334
 
 
2335
    /// get a pointer to the value (object)
 
2336
    const object_t* get_impl_ptr(const object_t*) const noexcept
 
2337
    {
 
2338
        return is_object() ? m_value.object : nullptr;
 
2339
    }
 
2340
 
 
2341
    /// get a pointer to the value (array)
 
2342
    array_t* get_impl_ptr(array_t*) noexcept
 
2343
    {
 
2344
        return is_array() ? m_value.array : nullptr;
 
2345
    }
 
2346
 
 
2347
    /// get a pointer to the value (array)
 
2348
    const array_t* get_impl_ptr(const array_t*) const noexcept
 
2349
    {
 
2350
        return is_array() ? m_value.array : nullptr;
 
2351
    }
 
2352
 
 
2353
    /// get a pointer to the value (string)
 
2354
    string_t* get_impl_ptr(string_t*) noexcept
 
2355
    {
 
2356
        return is_string() ? m_value.string : nullptr;
 
2357
    }
 
2358
 
 
2359
    /// get a pointer to the value (string)
 
2360
    const string_t* get_impl_ptr(const string_t*) const noexcept
 
2361
    {
 
2362
        return is_string() ? m_value.string : nullptr;
 
2363
    }
 
2364
 
 
2365
    /// get a pointer to the value (boolean)
 
2366
    boolean_t* get_impl_ptr(boolean_t*) noexcept
 
2367
    {
 
2368
        return is_boolean() ? &m_value.boolean : nullptr;
 
2369
    }
 
2370
 
 
2371
    /// get a pointer to the value (boolean)
 
2372
    const boolean_t* get_impl_ptr(const boolean_t*) const noexcept
 
2373
    {
 
2374
        return is_boolean() ? &m_value.boolean : nullptr;
 
2375
    }
 
2376
 
 
2377
    /// get a pointer to the value (integer number)
 
2378
    number_integer_t* get_impl_ptr(number_integer_t*) noexcept
 
2379
    {
 
2380
        return is_number_integer() ? &m_value.number_integer : nullptr;
 
2381
    }
 
2382
 
 
2383
    /// get a pointer to the value (integer number)
 
2384
    const number_integer_t* get_impl_ptr(const number_integer_t*) const noexcept
 
2385
    {
 
2386
        return is_number_integer() ? &m_value.number_integer : nullptr;
 
2387
    }
 
2388
 
 
2389
    /// get a pointer to the value (floating-point number)
 
2390
    number_float_t* get_impl_ptr(number_float_t*) noexcept
 
2391
    {
 
2392
        return is_number_float() ? &m_value.number_float : nullptr;
 
2393
    }
 
2394
 
 
2395
    /// get a pointer to the value (floating-point number)
 
2396
    const number_float_t* get_impl_ptr(const number_float_t*) const noexcept
 
2397
    {
 
2398
        return is_number_float() ? &m_value.number_float : nullptr;
 
2399
    }
 
2400
 
 
2401
  public:
 
2402
 
 
2403
    /// @name value access
 
2404
    /// @{
 
2405
 
 
2406
    /*!
 
2407
    @brief get a value (explicit)
 
2408
 
 
2409
    Explicit type conversion between the JSON value and a compatible value.
 
2410
 
 
2411
    @tparam ValueType non-pointer type compatible to the JSON value, for
 
2412
    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
 
2413
    `std::vector` types for JSON arrays
 
2414
 
 
2415
    @return copy of the JSON value, converted to type @a ValueType
 
2416
 
 
2417
    @throw std::domain_error in case passed type @a ValueType is incompatible
 
2418
    to JSON; example: `"type must be object, but is null"`
 
2419
 
 
2420
    @complexity Linear in the size of the JSON value.
 
2421
 
 
2422
    @liveexample{The example below shows serveral conversions from JSON values
 
2423
    to other types. There a few things to note: (1) Floating-point numbers can
 
2424
    be converted to integers\, (2) A JSON array can be converted to a standard
 
2425
    `std::vector<short>`\, (3) A JSON object can be converted to C++
 
2426
    assiciative containers such as `std::unordered_map<std::string\,
 
2427
    json>`.,get__ValueType_const}
 
2428
 
 
2429
    @internal
 
2430
    The idea of using a casted null pointer to choose the correct
 
2431
    implementation is from <http://stackoverflow.com/a/8315197/266378>.
 
2432
    @endinternal
 
2433
 
 
2434
    @sa @ref operator ValueType() const for implicit conversion
 
2435
    @sa @ref get() for pointer-member access
 
2436
 
 
2437
    @since version 1.0.0
 
2438
    */
 
2439
    template<typename ValueType, typename
 
2440
             std::enable_if<
 
2441
                 not std::is_pointer<ValueType>::value
 
2442
                 , int>::type = 0>
 
2443
    ValueType get() const
 
2444
    {
 
2445
        return get_impl(static_cast<ValueType*>(nullptr));
 
2446
    }
 
2447
 
 
2448
    /*!
 
2449
    @brief get a pointer value (explicit)
 
2450
 
 
2451
    Explicit pointer access to the internally stored JSON value. No copies are
 
2452
    made.
 
2453
 
 
2454
    @warning The pointer becomes invalid if the underlying JSON object changes.
 
2455
 
 
2456
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
 
2457
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref
 
2458
    number_float_t.
 
2459
 
 
2460
    @return pointer to the internally stored JSON value if the requested
 
2461
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
 
2462
 
 
2463
    @complexity Constant.
 
2464
 
 
2465
    @liveexample{The example below shows how pointers to internal values of a
 
2466
    JSON value can be requested. Note that no type conversions are made and a
 
2467
    `nullptr` is returned if the value and the requested pointer type does not
 
2468
    match.,get__PointerType}
 
2469
 
 
2470
    @sa @ref get_ptr() for explicit pointer-member access
 
2471
 
 
2472
    @since version 1.0.0
 
2473
    */
 
2474
    template<typename PointerType, typename
 
2475
             std::enable_if<
 
2476
                 std::is_pointer<PointerType>::value
 
2477
                 , int>::type = 0>
 
2478
    PointerType get() noexcept
 
2479
    {
 
2480
        // delegate the call to get_ptr
 
2481
        return get_ptr<PointerType>();
 
2482
    }
 
2483
 
 
2484
    /*!
 
2485
    @brief get a pointer value (explicit)
 
2486
    @copydoc get()
 
2487
    */
 
2488
    template<typename PointerType, typename
 
2489
             std::enable_if<
 
2490
                 std::is_pointer<PointerType>::value
 
2491
                 , int>::type = 0>
 
2492
    const PointerType get() const noexcept
 
2493
    {
 
2494
        // delegate the call to get_ptr
 
2495
        return get_ptr<PointerType>();
 
2496
    }
 
2497
 
 
2498
    /*!
 
2499
    @brief get a pointer value (implicit)
 
2500
 
 
2501
    Implict pointer access to the internally stored JSON value. No copies are
 
2502
    made.
 
2503
 
 
2504
    @warning Writing data to the pointee of the result yields an undefined
 
2505
    state.
 
2506
 
 
2507
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
 
2508
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref
 
2509
    number_float_t.
 
2510
 
 
2511
    @return pointer to the internally stored JSON value if the requested
 
2512
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
 
2513
 
 
2514
    @complexity Constant.
 
2515
 
 
2516
    @liveexample{The example below shows how pointers to internal values of a
 
2517
    JSON value can be requested. Note that no type conversions are made and a
 
2518
    `nullptr` is returned if the value and the requested pointer type does not
 
2519
    match.,get_ptr}
 
2520
 
 
2521
    @since version 1.0.0
 
2522
    */
 
2523
    template<typename PointerType, typename
 
2524
             std::enable_if<
 
2525
                 std::is_pointer<PointerType>::value
 
2526
                 , int>::type = 0>
 
2527
    PointerType get_ptr() noexcept
 
2528
    {
 
2529
        // delegate the call to get_impl_ptr<>()
 
2530
        return get_impl_ptr(static_cast<PointerType>(nullptr));
 
2531
    }
 
2532
 
 
2533
    /*!
 
2534
    @brief get a pointer value (implicit)
 
2535
    @copydoc get_ptr()
 
2536
    */
 
2537
    template<typename PointerType, typename
 
2538
             std::enable_if<
 
2539
                 std::is_pointer<PointerType>::value
 
2540
                 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
 
2541
                 , int>::type = 0>
 
2542
    const PointerType get_ptr() const noexcept
 
2543
    {
 
2544
        // delegate the call to get_impl_ptr<>() const
 
2545
        return get_impl_ptr(static_cast<const PointerType>(nullptr));
 
2546
    }
 
2547
 
 
2548
    /*!
 
2549
    @brief get a value (implicit)
 
2550
 
 
2551
    Implict type conversion between the JSON value and a compatible value. The
 
2552
    call is realized by calling @ref get() const.
 
2553
 
 
2554
    @tparam ValueType non-pointer type compatible to the JSON value, for
 
2555
    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
 
2556
    `std::vector` types for JSON arrays. The character type of @ref string_t
 
2557
    as well as an initializer list of this type is excluded to avoid
 
2558
    ambiguities as these types implicitly convert to `std::string`.
 
2559
 
 
2560
    @return copy of the JSON value, converted to type @a ValueType
 
2561
 
 
2562
    @throw std::domain_error in case passed type @a ValueType is incompatible
 
2563
    to JSON, thrown by @ref get() const
 
2564
 
 
2565
    @complexity Linear in the size of the JSON value.
 
2566
 
 
2567
    @liveexample{The example below shows serveral conversions from JSON values
 
2568
    to other types. There a few things to note: (1) Floating-point numbers can
 
2569
    be converted to integers\, (2) A JSON array can be converted to a standard
 
2570
    `std::vector<short>`\, (3) A JSON object can be converted to C++
 
2571
    assiciative containers such as `std::unordered_map<std::string\,
 
2572
    json>`.,operator__ValueType}
 
2573
 
 
2574
    @since version 1.0.0
 
2575
    */
 
2576
    template<typename ValueType, typename
 
2577
             std::enable_if<
 
2578
                 not std::is_pointer<ValueType>::value
 
2579
                 and not std::is_same<ValueType, typename string_t::value_type>::value
 
2580
                 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
 
2581
                 , int>::type = 0>
 
2582
    operator ValueType() const
 
2583
    {
 
2584
        // delegate the call to get<>() const
 
2585
        return get<ValueType>();
 
2586
    }
 
2587
 
 
2588
    /// @}
 
2589
 
 
2590
 
 
2591
    ////////////////////
 
2592
    // element access //
 
2593
    ////////////////////
 
2594
 
 
2595
    /// @name element access
 
2596
    /// @{
 
2597
 
 
2598
    /*!
 
2599
    @brief access specified array element with bounds checking
 
2600
 
 
2601
    Returns a reference to the element at specified location @a idx, with
 
2602
    bounds checking.
 
2603
 
 
2604
    @param[in] idx  index of the element to access
 
2605
 
 
2606
    @return reference to the element at index @a idx
 
2607
 
 
2608
    @throw std::domain_error if the JSON value is not an array; example:
 
2609
    `"cannot use at() with string"`
 
2610
    @throw std::out_of_range if the index @a idx is out of range of the array;
 
2611
    that is, `idx >= size()`; example: `"array index 7 is out of range"`
 
2612
 
 
2613
    @complexity Constant.
 
2614
 
 
2615
    @liveexample{The example below shows how array elements can be read and
 
2616
    written using at.,at__size_type}
 
2617
 
 
2618
    @since version 1.0.0
 
2619
    */
 
2620
    reference at(size_type idx)
 
2621
    {
 
2622
        // at only works for arrays
 
2623
        if (is_array())
 
2624
        {
 
2625
            try
 
2626
            {
 
2627
                return m_value.array->at(idx);
 
2628
            }
 
2629
            catch (std::out_of_range& e)
 
2630
            {
 
2631
                // create better exception explanation
 
2632
                throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
 
2633
            }
 
2634
        }
 
2635
        else
 
2636
        {
 
2637
            throw std::domain_error("cannot use at() with " + type_name());
 
2638
        }
 
2639
    }
 
2640
 
 
2641
    /*!
 
2642
    @brief access specified array element with bounds checking
 
2643
 
 
2644
    Returns a const reference to the element at specified location @a idx, with
 
2645
    bounds checking.
 
2646
 
 
2647
    @param[in] idx  index of the element to access
 
2648
 
 
2649
    @return const reference to the element at index @a idx
 
2650
 
 
2651
    @throw std::domain_error if the JSON value is not an array; example:
 
2652
    `"cannot use at() with string"`
 
2653
    @throw std::out_of_range if the index @a idx is out of range of the array;
 
2654
    that is, `idx >= size()`; example: `"array index 7 is out of range"`
 
2655
 
 
2656
    @complexity Constant.
 
2657
 
 
2658
    @liveexample{The example below shows how array elements can be read using
 
2659
    at.,at__size_type_const}
 
2660
 
 
2661
    @since version 1.0.0
 
2662
    */
 
2663
    const_reference at(size_type idx) const
 
2664
    {
 
2665
        // at only works for arrays
 
2666
        if (is_array())
 
2667
        {
 
2668
            try
 
2669
            {
 
2670
                return m_value.array->at(idx);
 
2671
            }
 
2672
            catch (std::out_of_range& e)
 
2673
            {
 
2674
                // create better exception explanation
 
2675
                throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
 
2676
            }
 
2677
        }
 
2678
        else
 
2679
        {
 
2680
            throw std::domain_error("cannot use at() with " + type_name());
 
2681
        }
 
2682
    }
 
2683
 
 
2684
    /*!
 
2685
    @brief access specified object element with bounds checking
 
2686
 
 
2687
    Returns a reference to the element at with specified key @a key, with
 
2688
    bounds checking.
 
2689
 
 
2690
    @param[in] key  key of the element to access
 
2691
 
 
2692
    @return reference to the element at key @a key
 
2693
 
 
2694
    @throw std::domain_error if the JSON value is not an object; example:
 
2695
    `"cannot use at() with boolean"`
 
2696
    @throw std::out_of_range if the key @a key is is not stored in the object;
 
2697
    that is, `find(key) == end()`; example: `"key "the fast" not found"`
 
2698
 
 
2699
    @complexity Logarithmic in the size of the container.
 
2700
 
 
2701
    @liveexample{The example below shows how object elements can be read and
 
2702
    written using at.,at__object_t_key_type}
 
2703
 
 
2704
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
 
2705
    access by reference
 
2706
    @sa @ref value() for access by value with a default value
 
2707
 
 
2708
    @since version 1.0.0
 
2709
    */
 
2710
    reference at(const typename object_t::key_type& key)
 
2711
    {
 
2712
        // at only works for objects
 
2713
        if (is_object())
 
2714
        {
 
2715
            try
 
2716
            {
 
2717
                return m_value.object->at(key);
 
2718
            }
 
2719
            catch (std::out_of_range& e)
 
2720
            {
 
2721
                // create better exception explanation
 
2722
                throw std::out_of_range("key '" + key + "' not found");
 
2723
            }
 
2724
        }
 
2725
        else
 
2726
        {
 
2727
            throw std::domain_error("cannot use at() with " + type_name());
 
2728
        }
 
2729
    }
 
2730
 
 
2731
    /*!
 
2732
    @brief access specified object element with bounds checking
 
2733
 
 
2734
    Returns a const reference to the element at with specified key @a key, with
 
2735
    bounds checking.
 
2736
 
 
2737
    @param[in] key  key of the element to access
 
2738
 
 
2739
    @return const reference to the element at key @a key
 
2740
 
 
2741
    @throw std::domain_error if the JSON value is not an object; example:
 
2742
    `"cannot use at() with boolean"`
 
2743
    @throw std::out_of_range if the key @a key is is not stored in the object;
 
2744
    that is, `find(key) == end()`; example: `"key "the fast" not found"`
 
2745
 
 
2746
    @complexity Logarithmic in the size of the container.
 
2747
 
 
2748
    @liveexample{The example below shows how object elements can be read using
 
2749
    at.,at__object_t_key_type_const}
 
2750
 
 
2751
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
 
2752
    access by reference
 
2753
    @sa @ref value() for access by value with a default value
 
2754
 
 
2755
    @since version 1.0.0
 
2756
    */
 
2757
    const_reference at(const typename object_t::key_type& key) const
 
2758
    {
 
2759
        // at only works for objects
 
2760
        if (is_object())
 
2761
        {
 
2762
            try
 
2763
            {
 
2764
                return m_value.object->at(key);
 
2765
            }
 
2766
            catch (std::out_of_range& e)
 
2767
            {
 
2768
                // create better exception explanation
 
2769
                throw std::out_of_range("key '" + key + "' not found");
 
2770
            }
 
2771
        }
 
2772
        else
 
2773
        {
 
2774
            throw std::domain_error("cannot use at() with " + type_name());
 
2775
        }
 
2776
    }
 
2777
 
 
2778
    /*!
 
2779
    @brief access specified array element
 
2780
 
 
2781
    Returns a reference to the element at specified location @a idx.
 
2782
 
 
2783
    @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
 
2784
    then the array is silently filled up with `null` values to make `idx` a
 
2785
    valid reference to the last stored element.
 
2786
 
 
2787
    @param[in] idx  index of the element to access
 
2788
 
 
2789
    @return reference to the element at index @a idx
 
2790
 
 
2791
    @throw std::domain_error if JSON is not an array or null; example: `"cannot
 
2792
    use operator[] with null"`
 
2793
 
 
2794
    @complexity Constant if @a idx is in the range of the array. Otherwise
 
2795
    linear in `idx - size()`.
 
2796
 
 
2797
    @liveexample{The example below shows how array elements can be read and
 
2798
    written using [] operator. Note the addition of `null`
 
2799
    values.,operatorarray__size_type}
 
2800
 
 
2801
    @since version 1.0.0
 
2802
    */
 
2803
    reference operator[](size_type idx)
 
2804
    {
 
2805
        // implicitly convert null to object
 
2806
        if (is_null())
 
2807
        {
 
2808
            m_type = value_t::array;
 
2809
            m_value.array = create<array_t>();
 
2810
        }
 
2811
 
 
2812
        // [] only works for arrays
 
2813
        if (is_array())
 
2814
        {
 
2815
            for (size_t i = m_value.array->size(); i <= idx; ++i)
 
2816
            {
 
2817
                m_value.array->push_back(basic_json());
 
2818
            }
 
2819
 
 
2820
            return m_value.array->operator[](idx);
 
2821
        }
 
2822
        else
 
2823
        {
 
2824
            throw std::domain_error("cannot use operator[] with " + type_name());
 
2825
        }
 
2826
    }
 
2827
 
 
2828
    /*!
 
2829
    @brief access specified array element
 
2830
 
 
2831
    Returns a const reference to the element at specified location @a idx.
 
2832
 
 
2833
    @param[in] idx  index of the element to access
 
2834
 
 
2835
    @return const reference to the element at index @a idx
 
2836
 
 
2837
    @throw std::domain_error if JSON is not an array; example: `"cannot use
 
2838
    operator[] with null"`
 
2839
 
 
2840
    @complexity Constant.
 
2841
 
 
2842
    @liveexample{The example below shows how array elements can be read using
 
2843
    the [] operator.,operatorarray__size_type_const}
 
2844
 
 
2845
    @since version 1.0.0
 
2846
    */
 
2847
    const_reference operator[](size_type idx) const
 
2848
    {
 
2849
        // at only works for arrays
 
2850
        if (is_array())
 
2851
        {
 
2852
            return m_value.array->operator[](idx);
 
2853
        }
 
2854
        else
 
2855
        {
 
2856
            throw std::domain_error("cannot use operator[] with " + type_name());
 
2857
        }
 
2858
    }
 
2859
 
 
2860
    /*!
 
2861
    @brief access specified object element
 
2862
 
 
2863
    Returns a reference to the element at with specified key @a key.
 
2864
 
 
2865
    @note If @a key is not found in the object, then it is silently added to
 
2866
    the object and filled with a `null` value to make `key` a valid reference.
 
2867
    In case the value was `null` before, it is converted to an object.
 
2868
 
 
2869
    @param[in] key  key of the element to access
 
2870
 
 
2871
    @return reference to the element at key @a key
 
2872
 
 
2873
    @throw std::domain_error if JSON is not an object or null; example:
 
2874
    `"cannot use operator[] with null"`
 
2875
 
 
2876
    @complexity Logarithmic in the size of the container.
 
2877
 
 
2878
    @liveexample{The example below shows how object elements can be read and
 
2879
    written using the [] operator.,operatorarray__key_type}
 
2880
 
 
2881
    @sa @ref at(const typename object_t::key_type&) for access by reference
 
2882
    with range checking
 
2883
    @sa @ref value() for access by value with a default value
 
2884
 
 
2885
    @since version 1.0.0
 
2886
    */
 
2887
    reference operator[](const typename object_t::key_type& key)
 
2888
    {
 
2889
        // implicitly convert null to object
 
2890
        if (is_null())
 
2891
        {
 
2892
            m_type = value_t::object;
 
2893
            m_value.object = create<object_t>();
 
2894
        }
 
2895
 
 
2896
        // [] only works for objects
 
2897
        if (is_object())
 
2898
        {
 
2899
            return m_value.object->operator[](key);
 
2900
        }
 
2901
        else
 
2902
        {
 
2903
            throw std::domain_error("cannot use operator[] with " + type_name());
 
2904
        }
 
2905
    }
 
2906
 
 
2907
    /*!
 
2908
    @brief read-only access specified object element
 
2909
 
 
2910
    Returns a const reference to the element at with specified key @a key. No
 
2911
    bounds checking is performed.
 
2912
 
 
2913
    @warning If the element with key @a key does not exist, the behavior is
 
2914
    undefined.
 
2915
 
 
2916
    @param[in] key  key of the element to access
 
2917
 
 
2918
    @return const reference to the element at key @a key
 
2919
 
 
2920
    @throw std::domain_error if JSON is not an object; example: `"cannot use
 
2921
    operator[] with null"`
 
2922
 
 
2923
    @complexity Logarithmic in the size of the container.
 
2924
 
 
2925
    @liveexample{The example below shows how object elements can be read using
 
2926
    the [] operator.,operatorarray__key_type_const}
 
2927
 
 
2928
    @sa @ref at(const typename object_t::key_type&) for access by reference
 
2929
    with range checking
 
2930
    @sa @ref value() for access by value with a default value
 
2931
 
 
2932
    @since version 1.0.0
 
2933
    */
 
2934
    const_reference operator[](const typename object_t::key_type& key) const
 
2935
    {
 
2936
        // [] only works for objects
 
2937
        if (is_object())
 
2938
        {
 
2939
            return m_value.object->find(key)->second;
 
2940
        }
 
2941
        else
 
2942
        {
 
2943
            throw std::domain_error("cannot use operator[] with " + type_name());
 
2944
        }
 
2945
    }
 
2946
 
 
2947
    /*!
 
2948
    @brief access specified object element
 
2949
 
 
2950
    Returns a reference to the element at with specified key @a key.
 
2951
 
 
2952
    @note If @a key is not found in the object, then it is silently added to
 
2953
    the object and filled with a `null` value to make `key` a valid reference.
 
2954
    In case the value was `null` before, it is converted to an object.
 
2955
 
 
2956
    @note This function is required for compatibility reasons with Clang.
 
2957
 
 
2958
    @param[in] key  key of the element to access
 
2959
 
 
2960
    @return reference to the element at key @a key
 
2961
 
 
2962
    @throw std::domain_error if JSON is not an object or null; example:
 
2963
    `"cannot use operator[] with null"`
 
2964
 
 
2965
    @complexity Logarithmic in the size of the container.
 
2966
 
 
2967
    @liveexample{The example below shows how object elements can be read and
 
2968
    written using the [] operator.,operatorarray__key_type}
 
2969
 
 
2970
    @sa @ref at(const typename object_t::key_type&) for access by reference
 
2971
    with range checking
 
2972
    @sa @ref value() for access by value with a default value
 
2973
 
 
2974
    @since version 1.0.0
 
2975
    */
 
2976
    template<typename T, std::size_t n>
 
2977
    reference operator[](const T (&key)[n])
 
2978
    {
 
2979
        // implicitly convert null to object
 
2980
        if (is_null())
 
2981
        {
 
2982
            m_type = value_t::object;
 
2983
            m_value = value_t::object;
 
2984
        }
 
2985
 
 
2986
        // at only works for objects
 
2987
        if (is_object())
 
2988
        {
 
2989
            return m_value.object->operator[](key);
 
2990
        }
 
2991
        else
 
2992
        {
 
2993
            throw std::domain_error("cannot use operator[] with " + type_name());
 
2994
        }
 
2995
    }
 
2996
 
 
2997
    /*!
 
2998
    @brief read-only access specified object element
 
2999
 
 
3000
    Returns a const reference to the element at with specified key @a key. No
 
3001
    bounds checking is performed.
 
3002
 
 
3003
    @warning If the element with key @a key does not exist, the behavior is
 
3004
    undefined.
 
3005
 
 
3006
    @note This function is required for compatibility reasons with Clang.
 
3007
 
 
3008
    @param[in] key  key of the element to access
 
3009
 
 
3010
    @return const reference to the element at key @a key
 
3011
 
 
3012
    @throw std::domain_error if JSON is not an object; example: `"cannot use
 
3013
    operator[] with null"`
 
3014
 
 
3015
    @complexity Logarithmic in the size of the container.
 
3016
 
 
3017
    @liveexample{The example below shows how object elements can be read using
 
3018
    the [] operator.,operatorarray__key_type_const}
 
3019
 
 
3020
    @sa @ref at(const typename object_t::key_type&) for access by reference
 
3021
    with range checking
 
3022
    @sa @ref value() for access by value with a default value
 
3023
 
 
3024
    @since version 1.0.0
 
3025
    */
 
3026
    template<typename T, std::size_t n>
 
3027
    const_reference operator[](const T (&key)[n]) const
 
3028
    {
 
3029
        // at only works for objects
 
3030
        if (is_object())
 
3031
        {
 
3032
            return m_value.object->find(key)->second;
 
3033
        }
 
3034
        else
 
3035
        {
 
3036
            throw std::domain_error("cannot use operator[] with " + type_name());
 
3037
        }
 
3038
    }
 
3039
 
 
3040
    /*!
 
3041
    @brief access specified object element with default value
 
3042
 
 
3043
    Returns either a copy of an object's element at the specified key @a key or
 
3044
    a given default value if no element with key @a key exists.
 
3045
 
 
3046
    The function is basically equivalent to executing
 
3047
    @code {.cpp}
 
3048
    try {
 
3049
        return at(key);
 
3050
    } catch(std::out_of_range) {
 
3051
        return default_value;
 
3052
    }
 
3053
    @endcode
 
3054
 
 
3055
    @note Unlike @ref at(const typename object_t::key_type&), this function
 
3056
    does not throw if the given key @a key was not found.
 
3057
 
 
3058
    @note Unlike @ref operator[](const typename object_t::key_type& key), this
 
3059
    function does not implicitly add an element to the position defined by @a
 
3060
    key. This function is furthermore also applicable to const objects.
 
3061
 
 
3062
    @param[in] key  key of the element to access
 
3063
    @param[in] default_value  the value to return if @a key is not found
 
3064
 
 
3065
    @tparam ValueType type compatible to JSON values, for instance `int` for
 
3066
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
 
3067
    JSON arrays. Note the type of the expected value at @a key and the default
 
3068
    value @a default_value must be compatible.
 
3069
 
 
3070
    @return copy of the element at key @a key or @a default_value if @a key
 
3071
    is not found
 
3072
 
 
3073
    @throw std::domain_error if JSON is not an object; example: `"cannot use
 
3074
    value() with null"`
 
3075
 
 
3076
    @complexity Logarithmic in the size of the container.
 
3077
 
 
3078
    @liveexample{The example below shows how object elements can be queried
 
3079
    with a default value.,basic_json__value}
 
3080
 
 
3081
    @sa @ref at(const typename object_t::key_type&) for access by reference
 
3082
    with range checking
 
3083
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
 
3084
    access by reference
 
3085
 
 
3086
    @since version 1.0.0
 
3087
    */
 
3088
    template <class ValueType, typename
 
3089
              std::enable_if<
 
3090
                  std::is_convertible<basic_json_t, ValueType>::value
 
3091
                  , int>::type = 0>
 
3092
    ValueType value(const typename object_t::key_type& key, ValueType default_value) const
 
3093
    {
 
3094
        // at only works for objects
 
3095
        if (is_object())
 
3096
        {
 
3097
            // if key is found, return value and given default value otherwise
 
3098
            const auto it = find(key);
 
3099
            if (it != end())
 
3100
            {
 
3101
                return *it;
 
3102
            }
 
3103
            else
 
3104
            {
 
3105
                return default_value;
 
3106
            }
 
3107
        }
 
3108
        else
 
3109
        {
 
3110
            throw std::domain_error("cannot use value() with " + type_name());
 
3111
        }
 
3112
    }
 
3113
 
 
3114
    /*!
 
3115
    @brief overload for a default value of type const char*
 
3116
    @copydoc basic_json::value()
 
3117
    */
 
3118
    string_t value(const typename object_t::key_type& key, const char* default_value) const
 
3119
    {
 
3120
        return value(key, string_t(default_value));
 
3121
    }
 
3122
 
 
3123
    /*!
 
3124
    @brief access the first element
 
3125
 
 
3126
    Returns a reference to the first element in the container. For a JSON
 
3127
    container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
 
3128
 
 
3129
    @return In case of a structured type (array or object), a reference to the
 
3130
    first element is returned. In cast of number, string, or boolean values, a
 
3131
    reference to the value is returned.
 
3132
 
 
3133
    @complexity Constant.
 
3134
 
 
3135
    @note Calling `front` on an empty container is undefined.
 
3136
 
 
3137
    @throw std::out_of_range when called on null value
 
3138
 
 
3139
    @liveexample{The following code shows an example for @ref front.,front}
 
3140
 
 
3141
    @since version 1.0.0
 
3142
    */
 
3143
    reference front()
 
3144
    {
 
3145
        return *begin();
 
3146
    }
 
3147
 
 
3148
    /*!
 
3149
    @copydoc basic_json::front()
 
3150
    */
 
3151
    const_reference front() const
 
3152
    {
 
3153
        return *cbegin();
 
3154
    }
 
3155
 
 
3156
    /*!
 
3157
    @brief access the last element
 
3158
 
 
3159
    Returns a reference to the last element in the container. For a JSON
 
3160
    container `c`, the expression `c.back()` is equivalent to `{ auto tmp =
 
3161
    c.end(); --tmp; return *tmp; }`.
 
3162
 
 
3163
    @return In case of a structured type (array or object), a reference to the
 
3164
    last element is returned. In cast of number, string, or boolean values, a
 
3165
    reference to the value is returned.
 
3166
 
 
3167
    @complexity Constant.
 
3168
 
 
3169
    @note Calling `back` on an empty container is undefined.
 
3170
 
 
3171
    @throw std::out_of_range when called on null value.
 
3172
 
 
3173
    @liveexample{The following code shows an example for @ref back.,back}
 
3174
 
 
3175
    @since version 1.0.0
 
3176
    */
 
3177
    reference back()
 
3178
    {
 
3179
        auto tmp = end();
 
3180
        --tmp;
 
3181
        return *tmp;
 
3182
    }
 
3183
 
 
3184
    /*!
 
3185
    @copydoc basic_json::back()
 
3186
    */
 
3187
    const_reference back() const
 
3188
    {
 
3189
        auto tmp = cend();
 
3190
        --tmp;
 
3191
        return *tmp;
 
3192
    }
 
3193
 
 
3194
    /*!
 
3195
    @brief remove element given an iterator
 
3196
 
 
3197
    Removes the element specified by iterator @a pos. Invalidates iterators and
 
3198
    references at or after the point of the erase, including the end()
 
3199
    iterator. The iterator @a pos must be valid and dereferenceable. Thus the
 
3200
    end() iterator (which is valid, but is not dereferencable) cannot be used
 
3201
    as a value for @a pos.
 
3202
 
 
3203
    If called on a primitive type other than null, the resulting JSON value
 
3204
    will be `null`.
 
3205
 
 
3206
    @param[in] pos iterator to the element to remove
 
3207
    @return Iterator following the last removed element. If the iterator @a pos
 
3208
    refers to the last element, the end() iterator is returned.
 
3209
 
 
3210
    @tparam InteratorType an @ref iterator or @ref const_iterator
 
3211
 
 
3212
    @throw std::domain_error if called on a `null` value; example: `"cannot use
 
3213
    erase() with null"`
 
3214
    @throw std::domain_error if called on an iterator which does not belong to
 
3215
    the current JSON value; example: `"iterator does not fit current value"`
 
3216
    @throw std::out_of_range if called on a primitive type with invalid
 
3217
    iterator (i.e., any iterator which is not end()); example: `"iterator out
 
3218
    of range"`
 
3219
 
 
3220
    @complexity The complexity depends on the type:
 
3221
    - objects: amortized constant
 
3222
    - arrays: linear in distance between pos and the end of the container
 
3223
    - strings: linear in the length of the string
 
3224
    - other types: constant
 
3225
 
 
3226
    @liveexample{The example shows the result of erase for different JSON
 
3227
    types.,erase__IteratorType}
 
3228
 
 
3229
    @sa @ref erase(InteratorType, InteratorType) -- removes the elements in the
 
3230
    given range
 
3231
    @sa @ref erase(const typename object_t::key_type&) -- remvoes the element
 
3232
    from an object at the given key
 
3233
    @sa @ref erase(const size_type) -- removes the element from an array at the
 
3234
    given index
 
3235
 
 
3236
    @since version 1.0.0
 
3237
    */
 
3238
    template <class InteratorType, typename
 
3239
              std::enable_if<
 
3240
                  std::is_same<InteratorType, typename basic_json_t::iterator>::value or
 
3241
                  std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
 
3242
                  , int>::type
 
3243
              = 0>
 
3244
    InteratorType erase(InteratorType pos)
 
3245
    {
 
3246
        // make sure iterator fits the current value
 
3247
        if (this != pos.m_object)
 
3248
        {
 
3249
            throw std::domain_error("iterator does not fit current value");
 
3250
        }
 
3251
 
 
3252
        InteratorType result = end();
 
3253
 
 
3254
        switch (m_type)
 
3255
        {
 
3256
            case value_t::boolean:
 
3257
            case value_t::number_float:
 
3258
            case value_t::number_integer:
 
3259
            case value_t::string:
 
3260
            {
 
3261
                if (not pos.m_it.primitive_iterator.is_begin())
 
3262
                {
 
3263
                    throw std::out_of_range("iterator out of range");
 
3264
                }
 
3265
 
 
3266
                if (is_string())
 
3267
                {
 
3268
                    delete m_value.string;
 
3269
                    m_value.string = nullptr;
 
3270
                }
 
3271
 
 
3272
                m_type = value_t::null;
 
3273
                break;
 
3274
            }
 
3275
 
 
3276
            case value_t::object:
 
3277
            {
 
3278
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
 
3279
                break;
 
3280
            }
 
3281
 
 
3282
            case value_t::array:
 
3283
            {
 
3284
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
 
3285
                break;
 
3286
            }
 
3287
 
 
3288
            default:
 
3289
            {
 
3290
                throw std::domain_error("cannot use erase() with " + type_name());
 
3291
            }
 
3292
        }
 
3293
 
 
3294
        return result;
 
3295
    }
 
3296
 
 
3297
    /*!
 
3298
    @brief remove elements given an iterator range
 
3299
 
 
3300
    Removes the element specified by the range `[first; last)`. Invalidates
 
3301
    iterators and references at or after the point of the erase, including the
 
3302
    end() iterator. The iterator @a first does not need to be dereferenceable
 
3303
    if `first == last`: erasing an empty range is a no-op.
 
3304
 
 
3305
    If called on a primitive type other than null, the resulting JSON value
 
3306
    will be `null`.
 
3307
 
 
3308
    @param[in] first iterator to the beginning of the range to remove
 
3309
    @param[in] last iterator past the end of the range to remove
 
3310
    @return Iterator following the last removed element. If the iterator @a
 
3311
    second refers to the last element, the end() iterator is returned.
 
3312
 
 
3313
    @tparam InteratorType an @ref iterator or @ref const_iterator
 
3314
 
 
3315
    @throw std::domain_error if called on a `null` value; example: `"cannot use
 
3316
    erase() with null"`
 
3317
    @throw std::domain_error if called on iterators which does not belong to
 
3318
    the current JSON value; example: `"iterators do not fit current value"`
 
3319
    @throw std::out_of_range if called on a primitive type with invalid
 
3320
    iterators (i.e., if `first != begin()` and `last != end()`); example:
 
3321
    `"iterators out of range"`
 
3322
 
 
3323
    @complexity The complexity depends on the type:
 
3324
    - objects: `log(size()) + std::distance(first, last)`
 
3325
    - arrays: linear in the distance between @a first and @a last, plus linear
 
3326
      in the distance between @a last and end of the container
 
3327
    - strings: linear in the length of the string
 
3328
    - other types: constant
 
3329
 
 
3330
    @liveexample{The example shows the result of erase for different JSON
 
3331
    types.,erase__IteratorType_IteratorType}
 
3332
 
 
3333
    @sa @ref erase(InteratorType) -- removes the element at a given position
 
3334
    @sa @ref erase(const typename object_t::key_type&) -- remvoes the element
 
3335
    from an object at the given key
 
3336
    @sa @ref erase(const size_type) -- removes the element from an array at the
 
3337
    given index
 
3338
 
 
3339
    @since version 1.0.0
 
3340
    */
 
3341
    template <class InteratorType, typename
 
3342
              std::enable_if<
 
3343
                  std::is_same<InteratorType, typename basic_json_t::iterator>::value or
 
3344
                  std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
 
3345
                  , int>::type
 
3346
              = 0>
 
3347
    InteratorType erase(InteratorType first, InteratorType last)
 
3348
    {
 
3349
        // make sure iterator fits the current value
 
3350
        if (this != first.m_object or this != last.m_object)
 
3351
        {
 
3352
            throw std::domain_error("iterators do not fit current value");
 
3353
        }
 
3354
 
 
3355
        InteratorType result = end();
 
3356
 
 
3357
        switch (m_type)
 
3358
        {
 
3359
            case value_t::boolean:
 
3360
            case value_t::number_float:
 
3361
            case value_t::number_integer:
 
3362
            case value_t::string:
 
3363
            {
 
3364
                if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
 
3365
                {
 
3366
                    throw std::out_of_range("iterators out of range");
 
3367
                }
 
3368
 
 
3369
                if (is_string())
 
3370
                {
 
3371
                    delete m_value.string;
 
3372
                    m_value.string = nullptr;
 
3373
                }
 
3374
 
 
3375
                m_type = value_t::null;
 
3376
                break;
 
3377
            }
 
3378
 
 
3379
            case value_t::object:
 
3380
            {
 
3381
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
 
3382
                                              last.m_it.object_iterator);
 
3383
                break;
 
3384
            }
 
3385
 
 
3386
            case value_t::array:
 
3387
            {
 
3388
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
 
3389
                                             last.m_it.array_iterator);
 
3390
                break;
 
3391
            }
 
3392
 
 
3393
            default:
 
3394
            {
 
3395
                throw std::domain_error("cannot use erase() with " + type_name());
 
3396
            }
 
3397
        }
 
3398
 
 
3399
        return result;
 
3400
    }
 
3401
 
 
3402
    /*!
 
3403
    @brief remove element from a JSON object given a key
 
3404
 
 
3405
    Removes elements from a JSON object with the key value @a key.
 
3406
 
 
3407
    @param[in] key value of the elements to remove
 
3408
 
 
3409
    @return Number of elements removed. If ObjectType is the default `std::map`
 
3410
    type, the return value will always be `0` (@a key was not found) or `1` (@a
 
3411
    key was found).
 
3412
 
 
3413
    @throw std::domain_error when called on a type other than JSON object;
 
3414
    example: `"cannot use erase() with null"`
 
3415
 
 
3416
    @complexity `log(size()) + count(key)`
 
3417
 
 
3418
    @liveexample{The example shows the effect of erase.,erase__key_type}
 
3419
 
 
3420
    @sa @ref erase(InteratorType) -- removes the element at a given position
 
3421
    @sa @ref erase(InteratorType, InteratorType) -- removes the elements in the
 
3422
    given range
 
3423
    @sa @ref erase(const size_type) -- removes the element from an array at the
 
3424
    given index
 
3425
 
 
3426
    @since version 1.0.0
 
3427
    */
 
3428
    size_type erase(const typename object_t::key_type& key)
 
3429
    {
 
3430
        // this erase only works for objects
 
3431
        if (is_object())
 
3432
        {
 
3433
            return m_value.object->erase(key);
 
3434
        }
 
3435
        else
 
3436
        {
 
3437
            throw std::domain_error("cannot use erase() with " + type_name());
 
3438
        }
 
3439
    }
 
3440
 
 
3441
    /*!
 
3442
    @brief remove element from a JSON array given an index
 
3443
 
 
3444
    Removes element from a JSON array at the index @a idx.
 
3445
 
 
3446
    @param[in] idx index of the element to remove
 
3447
 
 
3448
    @throw std::domain_error when called on a type other than JSON array;
 
3449
    example: `"cannot use erase() with null"`
 
3450
    @throw std::out_of_range when `idx >= size()`; example: `"index out of
 
3451
    range"`
 
3452
 
 
3453
    @complexity Linear in distance between @a idx and the end of the container.
 
3454
 
 
3455
    @liveexample{The example shows the effect of erase.,erase__size_type}
 
3456
 
 
3457
    @sa @ref erase(InteratorType) -- removes the element at a given position
 
3458
    @sa @ref erase(InteratorType, InteratorType) -- removes the elements in the
 
3459
    given range
 
3460
    @sa @ref erase(const typename object_t::key_type&) -- remvoes the element
 
3461
    from an object at the given key
 
3462
 
 
3463
    @since version 1.0.0
 
3464
    */
 
3465
    void erase(const size_type idx)
 
3466
    {
 
3467
        // this erase only works for arrays
 
3468
        if (is_array())
 
3469
        {
 
3470
            if (idx >= size())
 
3471
            {
 
3472
                throw std::out_of_range("index out of range");
 
3473
            }
 
3474
 
 
3475
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
 
3476
        }
 
3477
        else
 
3478
        {
 
3479
            throw std::domain_error("cannot use erase() with " + type_name());
 
3480
        }
 
3481
    }
 
3482
 
 
3483
    /*!
 
3484
    @brief find an element in a JSON object
 
3485
 
 
3486
    Finds an element in a JSON object with key equivalent to @a key. If the
 
3487
    element is not found or the JSON value is not an object, end() is returned.
 
3488
 
 
3489
    @param[in] key key value of the element to search for
 
3490
 
 
3491
    @return Iterator to an element with key equivalent to @a key. If no such
 
3492
    element is found, past-the-end (see end()) iterator is returned.
 
3493
 
 
3494
    @complexity Logarithmic in the size of the JSON object.
 
3495
 
 
3496
    @liveexample{The example shows how find is used.,find__key_type}
 
3497
 
 
3498
    @since version 1.0.0
 
3499
    */
 
3500
    iterator find(typename object_t::key_type key)
 
3501
    {
 
3502
        auto result = end();
 
3503
 
 
3504
        if (is_object())
 
3505
        {
 
3506
            result.m_it.object_iterator = m_value.object->find(key);
 
3507
        }
 
3508
 
 
3509
        return result;
 
3510
    }
 
3511
 
 
3512
    /*!
 
3513
    @brief find an element in a JSON object
 
3514
    @copydoc find(typename object_t::key_type)
 
3515
    */
 
3516
    const_iterator find(typename object_t::key_type key) const
 
3517
    {
 
3518
        auto result = cend();
 
3519
 
 
3520
        if (is_object())
 
3521
        {
 
3522
            result.m_it.object_iterator = m_value.object->find(key);
 
3523
        }
 
3524
 
 
3525
        return result;
 
3526
    }
 
3527
 
 
3528
    /*!
 
3529
    @brief returns the number of occurrences of a key in a JSON object
 
3530
 
 
3531
    Returns the number of elements with key @a key. If ObjectType is the
 
3532
    default `std::map` type, the return value will always be `0` (@a key was
 
3533
    not found) or `1` (@a key was found).
 
3534
 
 
3535
    @param[in] key key value of the element to count
 
3536
 
 
3537
    @return Number of elements with key @a key. If the JSON value is not an
 
3538
    object, the return value will be `0`.
 
3539
 
 
3540
    @complexity Logarithmic in the size of the JSON object.
 
3541
 
 
3542
    @liveexample{The example shows how count is used.,count}
 
3543
 
 
3544
    @since version 1.0.0
 
3545
    */
 
3546
    size_type count(typename object_t::key_type key) const
 
3547
    {
 
3548
        // return 0 for all nonobject types
 
3549
        return is_object() ? m_value.object->count(key) : 0;
 
3550
    }
 
3551
 
 
3552
    /// @}
 
3553
 
 
3554
 
 
3555
    ///////////////
 
3556
    // iterators //
 
3557
    ///////////////
 
3558
 
 
3559
    /// @name iterators
 
3560
    /// @{
 
3561
 
 
3562
    /*!
 
3563
    @brief returns an iterator to the first element
 
3564
 
 
3565
    Returns an iterator to the first element.
 
3566
 
 
3567
    @image html range-begin-end.svg "Illustration from cppreference.com"
 
3568
 
 
3569
    @return iterator to the first element
 
3570
 
 
3571
    @complexity Constant.
 
3572
 
 
3573
    @requirement This function satisfies the Container requirements:
 
3574
    - The complexity is constant.
 
3575
 
 
3576
    @liveexample{The following code shows an example for @ref begin.,begin}
 
3577
 
 
3578
    @since version 1.0.0
 
3579
    */
 
3580
    iterator begin()
 
3581
    {
 
3582
        iterator result(this);
 
3583
        result.set_begin();
 
3584
        return result;
 
3585
    }
 
3586
 
 
3587
    /*!
 
3588
    @copydoc basic_json::cbegin()
 
3589
    */
 
3590
    const_iterator begin() const
 
3591
    {
 
3592
        return cbegin();
 
3593
    }
 
3594
 
 
3595
    /*!
 
3596
    @brief returns a const iterator to the first element
 
3597
 
 
3598
    Returns a const iterator to the first element.
 
3599
 
 
3600
    @image html range-begin-end.svg "Illustration from cppreference.com"
 
3601
 
 
3602
    @return const iterator to the first element
 
3603
 
 
3604
    @complexity Constant.
 
3605
 
 
3606
    @requirement This function satisfies the Container requirements:
 
3607
    - The complexity is constant.
 
3608
    - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
 
3609
 
 
3610
    @liveexample{The following code shows an example for @ref cbegin.,cbegin}
 
3611
 
 
3612
    @since version 1.0.0
 
3613
    */
 
3614
    const_iterator cbegin() const
 
3615
    {
 
3616
        const_iterator result(this);
 
3617
        result.set_begin();
 
3618
        return result;
 
3619
    }
 
3620
 
 
3621
    /*!
 
3622
    @brief returns an iterator to one past the last element
 
3623
 
 
3624
    Returns an iterator to one past the last element.
 
3625
 
 
3626
    @image html range-begin-end.svg "Illustration from cppreference.com"
 
3627
 
 
3628
    @return iterator one past the last element
 
3629
 
 
3630
    @complexity Constant.
 
3631
 
 
3632
    @requirement This function satisfies the Container requirements:
 
3633
    - The complexity is constant.
 
3634
 
 
3635
    @liveexample{The following code shows an example for @ref end.,end}
 
3636
 
 
3637
    @since version 1.0.0
 
3638
    */
 
3639
    iterator end()
 
3640
    {
 
3641
        iterator result(this);
 
3642
        result.set_end();
 
3643
        return result;
 
3644
    }
 
3645
 
 
3646
    /*!
 
3647
    @copydoc basic_json::cend()
 
3648
    */
 
3649
    const_iterator end() const
 
3650
    {
 
3651
        return cend();
 
3652
    }
 
3653
 
 
3654
    /*!
 
3655
    @brief returns a const iterator to one past the last element
 
3656
 
 
3657
    Returns a const iterator to one past the last element.
 
3658
 
 
3659
    @image html range-begin-end.svg "Illustration from cppreference.com"
 
3660
 
 
3661
    @return const iterator one past the last element
 
3662
 
 
3663
    @complexity Constant.
 
3664
 
 
3665
    @requirement This function satisfies the Container requirements:
 
3666
    - The complexity is constant.
 
3667
    - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
 
3668
 
 
3669
    @liveexample{The following code shows an example for @ref cend.,cend}
 
3670
 
 
3671
    @since version 1.0.0
 
3672
    */
 
3673
    const_iterator cend() const
 
3674
    {
 
3675
        const_iterator result(this);
 
3676
        result.set_end();
 
3677
        return result;
 
3678
    }
 
3679
 
 
3680
    /*!
 
3681
    @brief returns an iterator to the reverse-beginning
 
3682
 
 
3683
    Returns an iterator to the reverse-beginning; that is, the last element.
 
3684
 
 
3685
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
 
3686
 
 
3687
    @complexity Constant.
 
3688
 
 
3689
    @requirement This function satisfies the ReversibleContainer requirements:
 
3690
    - The complexity is constant.
 
3691
    - Has the semantics of `reverse_iterator(end())`.
 
3692
 
 
3693
    @liveexample{The following code shows an example for @ref rbegin.,rbegin}
 
3694
 
 
3695
    @since version 1.0.0
 
3696
    */
 
3697
    reverse_iterator rbegin()
 
3698
    {
 
3699
        return reverse_iterator(end());
 
3700
    }
 
3701
 
 
3702
    /*!
 
3703
    @copydoc basic_json::crbegin()
 
3704
    */
 
3705
    const_reverse_iterator rbegin() const
 
3706
    {
 
3707
        return crbegin();
 
3708
    }
 
3709
 
 
3710
    /*!
 
3711
    @brief returns an iterator to the reverse-end
 
3712
 
 
3713
    Returns an iterator to the reverse-end; that is, one before the first
 
3714
    element.
 
3715
 
 
3716
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
 
3717
 
 
3718
    @complexity Constant.
 
3719
 
 
3720
    @requirement This function satisfies the ReversibleContainer requirements:
 
3721
    - The complexity is constant.
 
3722
    - Has the semantics of `reverse_iterator(begin())`.
 
3723
 
 
3724
    @liveexample{The following code shows an example for @ref rend.,rend}
 
3725
 
 
3726
    @since version 1.0.0
 
3727
    */
 
3728
    reverse_iterator rend()
 
3729
    {
 
3730
        return reverse_iterator(begin());
 
3731
    }
 
3732
 
 
3733
    /*!
 
3734
    @copydoc basic_json::crend()
 
3735
    */
 
3736
    const_reverse_iterator rend() const
 
3737
    {
 
3738
        return crend();
 
3739
    }
 
3740
 
 
3741
    /*!
 
3742
    @brief returns a const reverse iterator to the last element
 
3743
 
 
3744
    Returns a const iterator to the reverse-beginning; that is, the last
 
3745
    element.
 
3746
 
 
3747
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
 
3748
 
 
3749
    @complexity Constant.
 
3750
 
 
3751
    @requirement This function satisfies the ReversibleContainer requirements:
 
3752
    - The complexity is constant.
 
3753
    - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
 
3754
 
 
3755
    @liveexample{The following code shows an example for @ref crbegin.,crbegin}
 
3756
 
 
3757
    @since version 1.0.0
 
3758
    */
 
3759
    const_reverse_iterator crbegin() const
 
3760
    {
 
3761
        return const_reverse_iterator(cend());
 
3762
    }
 
3763
 
 
3764
    /*!
 
3765
    @brief returns a const reverse iterator to one before the first
 
3766
 
 
3767
    Returns a const reverse iterator to the reverse-end; that is, one before
 
3768
    the first element.
 
3769
 
 
3770
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
 
3771
 
 
3772
    @complexity Constant.
 
3773
 
 
3774
    @requirement This function satisfies the ReversibleContainer requirements:
 
3775
    - The complexity is constant.
 
3776
    - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
 
3777
 
 
3778
    @liveexample{The following code shows an example for @ref crend.,crend}
 
3779
 
 
3780
    @since version 1.0.0
 
3781
    */
 
3782
    const_reverse_iterator crend() const
 
3783
    {
 
3784
        return const_reverse_iterator(cbegin());
 
3785
    }
 
3786
 
 
3787
  private:
 
3788
    // forward declaration
 
3789
    template<typename IteratorType> class iteration_proxy;
 
3790
 
 
3791
  public:
 
3792
    /*!
 
3793
    @brief wrapper to access iterator member functions in range-based for
 
3794
 
 
3795
    This functuion allows to access @ref iterator::key() and @ref
 
3796
    iterator::value() during range-based for loops. In these loops, a reference
 
3797
    to the JSON values is returned, so there is no access to the underlying
 
3798
    iterator.
 
3799
 
 
3800
    @note The name of this function is not yet final and may change in the
 
3801
    future.
 
3802
    */
 
3803
    static iteration_proxy<iterator> iterator_wrapper(reference cont)
 
3804
    {
 
3805
        return iteration_proxy<iterator>(cont);
 
3806
    }
 
3807
 
 
3808
    /*!
 
3809
    @copydoc iterator_wrapper(reference)
 
3810
    */
 
3811
    static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
 
3812
    {
 
3813
        return iteration_proxy<const_iterator>(cont);
 
3814
    }
 
3815
 
 
3816
    /// @}
 
3817
 
 
3818
 
 
3819
    //////////////
 
3820
    // capacity //
 
3821
    //////////////
 
3822
 
 
3823
    /// @name capacity
 
3824
    /// @{
 
3825
 
 
3826
    /*!
 
3827
    @brief checks whether the container is empty
 
3828
 
 
3829
    Checks if a JSON value has no elements.
 
3830
 
 
3831
    @return The return value depends on the different types and is
 
3832
            defined as follows:
 
3833
            Value type  | return value
 
3834
            ----------- | -------------
 
3835
            null        | @c true
 
3836
            boolean     | @c false
 
3837
            string      | @c false
 
3838
            number      | @c false
 
3839
            object      | result of function object_t::empty()
 
3840
            array       | result of function array_t::empty()
 
3841
 
 
3842
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy the
 
3843
    Container concept; that is, their empty() functions have constant
 
3844
    complexity.
 
3845
 
 
3846
    @requirement This function satisfies the Container requirements:
 
3847
    - The complexity is constant.
 
3848
    - Has the semantics of `begin() == end()`.
 
3849
 
 
3850
    @liveexample{The following code uses @ref empty to check if a @ref json
 
3851
    object contains any elements.,empty}
 
3852
 
 
3853
    @since version 1.0.0
 
3854
    */
 
3855
    bool empty() const noexcept
 
3856
    {
 
3857
        switch (m_type)
 
3858
        {
 
3859
            case value_t::null:
 
3860
            {
 
3861
                // null values are empty
 
3862
                return true;
 
3863
            }
 
3864
 
 
3865
            case value_t::array:
 
3866
            {
 
3867
                return m_value.array->empty();
 
3868
            }
 
3869
 
 
3870
            case value_t::object:
 
3871
            {
 
3872
                return m_value.object->empty();
 
3873
            }
 
3874
 
 
3875
            default:
 
3876
            {
 
3877
                // all other types are nonempty
 
3878
                return false;
 
3879
            }
 
3880
        }
 
3881
    }
 
3882
 
 
3883
    /*!
 
3884
    @brief returns the number of elements
 
3885
 
 
3886
    Returns the number of elements in a JSON value.
 
3887
 
 
3888
    @return The return value depends on the different types and is
 
3889
            defined as follows:
 
3890
            Value type  | return value
 
3891
            ----------- | -------------
 
3892
            null        | @c 0
 
3893
            boolean     | @c 1
 
3894
            string      | @c 1
 
3895
            number      | @c 1
 
3896
            object      | result of function object_t::size()
 
3897
            array       | result of function array_t::size()
 
3898
 
 
3899
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy the
 
3900
    Container concept; that is, their size() functions have constant complexity.
 
3901
 
 
3902
    @requirement This function satisfies the Container requirements:
 
3903
    - The complexity is constant.
 
3904
    - Has the semantics of `std::distance(begin(), end())`.
 
3905
 
 
3906
    @liveexample{The following code calls @ref size on the different value
 
3907
    types.,size}
 
3908
 
 
3909
    @since version 1.0.0
 
3910
    */
 
3911
    size_type size() const noexcept
 
3912
    {
 
3913
        switch (m_type)
 
3914
        {
 
3915
            case value_t::null:
 
3916
            {
 
3917
                // null values are empty
 
3918
                return 0;
 
3919
            }
 
3920
 
 
3921
            case value_t::array:
 
3922
            {
 
3923
                return m_value.array->size();
 
3924
            }
 
3925
 
 
3926
            case value_t::object:
 
3927
            {
 
3928
                return m_value.object->size();
 
3929
            }
 
3930
 
 
3931
            default:
 
3932
            {
 
3933
                // all other types have size 1
 
3934
                return 1;
 
3935
            }
 
3936
        }
 
3937
    }
 
3938
 
 
3939
    /*!
 
3940
    @brief returns the maximum possible number of elements
 
3941
 
 
3942
    Returns the maximum number of elements a JSON value is able to hold due to
 
3943
    system or library implementation limitations, i.e. `std::distance(begin(),
 
3944
    end())` for the JSON value.
 
3945
 
 
3946
    @return The return value depends on the different types and is
 
3947
            defined as follows:
 
3948
            Value type  | return value
 
3949
            ----------- | -------------
 
3950
            null        | @c 0 (same as size())
 
3951
            boolean     | @c 1 (same as size())
 
3952
            string      | @c 1 (same as size())
 
3953
            number      | @c 1 (same as size())
 
3954
            object      | result of function object_t::max_size()
 
3955
            array       | result of function array_t::max_size()
 
3956
 
 
3957
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy the
 
3958
    Container concept; that is, their max_size() functions have constant
 
3959
    complexity.
 
3960
 
 
3961
    @requirement This function satisfies the Container requirements:
 
3962
    - The complexity is constant.
 
3963
    - Has the semantics of returning `b.size()` where `b` is the largest
 
3964
      possible JSON value.
 
3965
 
 
3966
    @liveexample{The following code calls @ref max_size on the different value
 
3967
    types. Note the output is implementation specific.,max_size}
 
3968
 
 
3969
    @since version 1.0.0
 
3970
    */
 
3971
    size_type max_size() const noexcept
 
3972
    {
 
3973
        switch (m_type)
 
3974
        {
 
3975
            case value_t::array:
 
3976
            {
 
3977
                return m_value.array->max_size();
 
3978
            }
 
3979
 
 
3980
            case value_t::object:
 
3981
            {
 
3982
                return m_value.object->max_size();
 
3983
            }
 
3984
 
 
3985
            default:
 
3986
            {
 
3987
                // all other types have max_size() == size()
 
3988
                return size();
 
3989
            }
 
3990
        }
 
3991
    }
 
3992
 
 
3993
    /// @}
 
3994
 
 
3995
 
 
3996
    ///////////////
 
3997
    // modifiers //
 
3998
    ///////////////
 
3999
 
 
4000
    /// @name modifiers
 
4001
    /// @{
 
4002
 
 
4003
    /*!
 
4004
    @brief clears the contents
 
4005
 
 
4006
    Clears the content of a JSON value and resets it to the default value as
 
4007
    if @ref basic_json(value_t) would have been called:
 
4008
 
 
4009
    Value type  | initial value
 
4010
    ----------- | -------------
 
4011
    null        | `null`
 
4012
    boolean     | `false`
 
4013
    string      | `""`
 
4014
    number      | `0`
 
4015
    object      | `{}`
 
4016
    array       | `[]`
 
4017
 
 
4018
    @note Floating-point numbers are set to `0.0` which will be serialized to
 
4019
    `0`. The vale type remains @ref number_float_t.
 
4020
 
 
4021
    @complexity Linear in the size of the JSON value.
 
4022
 
 
4023
    @liveexample{The example below shows the effect of @ref clear to different
 
4024
    JSON types.,clear}
 
4025
 
 
4026
    @since version 1.0.0
 
4027
    */
 
4028
    void clear() noexcept
 
4029
    {
 
4030
        switch (m_type)
 
4031
        {
 
4032
            case value_t::number_integer:
 
4033
            {
 
4034
                m_value.number_integer = 0;
 
4035
                break;
 
4036
            }
 
4037
 
 
4038
            case value_t::number_float:
 
4039
            {
 
4040
                m_value.number_float = 0.0;
 
4041
                break;
 
4042
            }
 
4043
 
 
4044
            case value_t::boolean:
 
4045
            {
 
4046
                m_value.boolean = false;
 
4047
                break;
 
4048
            }
 
4049
 
 
4050
            case value_t::string:
 
4051
            {
 
4052
                m_value.string->clear();
 
4053
                break;
 
4054
            }
 
4055
 
 
4056
            case value_t::array:
 
4057
            {
 
4058
                m_value.array->clear();
 
4059
                break;
 
4060
            }
 
4061
 
 
4062
            case value_t::object:
 
4063
            {
 
4064
                m_value.object->clear();
 
4065
                break;
 
4066
            }
 
4067
 
 
4068
            default:
 
4069
            {
 
4070
                break;
 
4071
            }
 
4072
        }
 
4073
    }
 
4074
 
 
4075
    /*!
 
4076
    @brief add an object to an array
 
4077
 
 
4078
    Appends the given element @a val to the end of the JSON value. If the
 
4079
    function is called on a JSON null value, an empty array is created before
 
4080
    appending @a val.
 
4081
 
 
4082
    @param val the value to add to the JSON array
 
4083
 
 
4084
    @throw std::domain_error when called on a type other than JSON array or
 
4085
    null; example: `"cannot use push_back() with number"`
 
4086
 
 
4087
    @complexity Amortized constant.
 
4088
 
 
4089
    @liveexample{The example shows how `push_back` and `+=` can be used to add
 
4090
    elements to a JSON array. Note how the `null` value was silently converted
 
4091
    to a JSON array.,push_back}
 
4092
 
 
4093
    @since version 1.0.0
 
4094
    */
 
4095
    void push_back(basic_json&& val)
 
4096
    {
 
4097
        // push_back only works for null objects or arrays
 
4098
        if (not(is_null() or is_array()))
 
4099
        {
 
4100
            throw std::domain_error("cannot use push_back() with " + type_name());
 
4101
        }
 
4102
 
 
4103
        // transform null object into an array
 
4104
        if (is_null())
 
4105
        {
 
4106
            m_type = value_t::array;
 
4107
            m_value = value_t::array;
 
4108
        }
 
4109
 
 
4110
        // add element to array (move semantics)
 
4111
        m_value.array->push_back(std::move(val));
 
4112
        // invalidate object
 
4113
        val.m_type = value_t::null;
 
4114
    }
 
4115
 
 
4116
    /*!
 
4117
    @brief add an object to an array
 
4118
    @copydoc push_back(basic_json&&)
 
4119
    */
 
4120
    reference operator+=(basic_json&& val)
 
4121
    {
 
4122
        push_back(std::move(val));
 
4123
        return *this;
 
4124
    }
 
4125
 
 
4126
    /*!
 
4127
    @brief add an object to an array
 
4128
    @copydoc push_back(basic_json&&)
 
4129
    */
 
4130
    void push_back(const basic_json& val)
 
4131
    {
 
4132
        // push_back only works for null objects or arrays
 
4133
        if (not(is_null() or is_array()))
 
4134
        {
 
4135
            throw std::domain_error("cannot use push_back() with " + type_name());
 
4136
        }
 
4137
 
 
4138
        // transform null object into an array
 
4139
        if (is_null())
 
4140
        {
 
4141
            m_type = value_t::array;
 
4142
            m_value = value_t::array;
 
4143
        }
 
4144
 
 
4145
        // add element to array
 
4146
        m_value.array->push_back(val);
 
4147
    }
 
4148
 
 
4149
    /*!
 
4150
    @brief add an object to an array
 
4151
    @copydoc push_back(basic_json&&)
 
4152
    */
 
4153
    reference operator+=(const basic_json& val)
 
4154
    {
 
4155
        push_back(val);
 
4156
        return *this;
 
4157
    }
 
4158
 
 
4159
    /*!
 
4160
    @brief add an object to an object
 
4161
 
 
4162
    Inserts the given element @a val to the JSON object. If the function is
 
4163
    called on a JSON null value, an empty object is created before inserting @a
 
4164
    val.
 
4165
 
 
4166
    @param[in] val the value to add to the JSON object
 
4167
 
 
4168
    @throw std::domain_error when called on a type other than JSON object or
 
4169
    null; example: `"cannot use push_back() with number"`
 
4170
 
 
4171
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
 
4172
 
 
4173
    @liveexample{The example shows how `push_back` and `+=` can be used to add
 
4174
    elements to a JSON object. Note how the `null` value was silently converted
 
4175
    to a JSON object.,push_back__object_t__value}
 
4176
 
 
4177
    @since version 1.0.0
 
4178
    */
 
4179
    void push_back(const typename object_t::value_type& val)
 
4180
    {
 
4181
        // push_back only works for null objects or objects
 
4182
        if (not(is_null() or is_object()))
 
4183
        {
 
4184
            throw std::domain_error("cannot use push_back() with " + type_name());
 
4185
        }
 
4186
 
 
4187
        // transform null object into an object
 
4188
        if (is_null())
 
4189
        {
 
4190
            m_type = value_t::object;
 
4191
            m_value = value_t::object;
 
4192
        }
 
4193
 
 
4194
        // add element to array
 
4195
        m_value.object->insert(val);
 
4196
    }
 
4197
 
 
4198
    /*!
 
4199
    @brief add an object to an object
 
4200
    @copydoc push_back(const typename object_t::value_type&)
 
4201
    */
 
4202
    reference operator+=(const typename object_t::value_type& val)
 
4203
    {
 
4204
        push_back(val);
 
4205
        return operator[](val.first);
 
4206
    }
 
4207
 
 
4208
    /*!
 
4209
    @brief inserts element
 
4210
 
 
4211
    Inserts element @a val before iterator @a pos.
 
4212
 
 
4213
    @param[in] pos iterator before which the content will be inserted; may be
 
4214
    the end() iterator
 
4215
    @param[in] val element to insert
 
4216
    @return iterator pointing to the inserted @a val.
 
4217
 
 
4218
    @throw std::domain_error if called on JSON values other than arrays;
 
4219
    example: `"cannot use insert() with string"`
 
4220
    @throw std::domain_error if @a pos is not an iterator of *this; example:
 
4221
    `"iterator does not fit current value"`
 
4222
 
 
4223
    @complexity Constant plus linear in the distance between pos and end of the
 
4224
    container.
 
4225
 
 
4226
    @liveexample{The example shows how insert is used.,insert}
 
4227
 
 
4228
    @since version 1.0.0
 
4229
    */
 
4230
    iterator insert(const_iterator pos, const basic_json& val)
 
4231
    {
 
4232
        // insert only works for arrays
 
4233
        if (is_array())
 
4234
        {
 
4235
            // check if iterator pos fits to this JSON value
 
4236
            if (pos.m_object != this)
 
4237
            {
 
4238
                throw std::domain_error("iterator does not fit current value");
 
4239
            }
 
4240
 
 
4241
            // insert to array and return iterator
 
4242
            iterator result(this);
 
4243
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
 
4244
            return result;
 
4245
        }
 
4246
        else
 
4247
        {
 
4248
            throw std::domain_error("cannot use insert() with " + type_name());
 
4249
        }
 
4250
    }
 
4251
 
 
4252
    /*!
 
4253
    @brief inserts element
 
4254
    @copydoc insert(const_iterator, const basic_json&)
 
4255
    */
 
4256
    iterator insert(const_iterator pos, basic_json&& val)
 
4257
    {
 
4258
        return insert(pos, val);
 
4259
    }
 
4260
 
 
4261
    /*!
 
4262
    @brief inserts elements
 
4263
 
 
4264
    Inserts @a cnt copies of @a val before iterator @a pos.
 
4265
 
 
4266
    @param[in] pos iterator before which the content will be inserted; may be
 
4267
    the end() iterator
 
4268
    @param[in] cnt number of copies of @a val to insert
 
4269
    @param[in] val element to insert
 
4270
    @return iterator pointing to the first element inserted, or @a pos if
 
4271
    `cnt==0`
 
4272
 
 
4273
    @throw std::domain_error if called on JSON values other than arrays;
 
4274
    example: `"cannot use insert() with string"`
 
4275
    @throw std::domain_error if @a pos is not an iterator of *this; example:
 
4276
    `"iterator does not fit current value"`
 
4277
 
 
4278
    @complexity Linear in @a cnt plus linear in the distance between @a pos
 
4279
    and end of the container.
 
4280
 
 
4281
    @liveexample{The example shows how insert is used.,insert__count}
 
4282
 
 
4283
    @since version 1.0.0
 
4284
    */
 
4285
    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
 
4286
    {
 
4287
        // insert only works for arrays
 
4288
        if (is_array())
 
4289
        {
 
4290
            // check if iterator pos fits to this JSON value
 
4291
            if (pos.m_object != this)
 
4292
            {
 
4293
                throw std::domain_error("iterator does not fit current value");
 
4294
            }
 
4295
 
 
4296
            // insert to array and return iterator
 
4297
            iterator result(this);
 
4298
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
 
4299
            return result;
 
4300
        }
 
4301
        else
 
4302
        {
 
4303
            throw std::domain_error("cannot use insert() with " + type_name());
 
4304
        }
 
4305
    }
 
4306
 
 
4307
    /*!
 
4308
    @brief inserts elements
 
4309
 
 
4310
    Inserts elements from range `[first, last)` before iterator @a pos.
 
4311
 
 
4312
    @param[in] pos iterator before which the content will be inserted; may be
 
4313
    the end() iterator
 
4314
    @param[in] first begin of the range of elements to insert
 
4315
    @param[in] last end of the range of elements to insert
 
4316
 
 
4317
    @throw std::domain_error if called on JSON values other than arrays;
 
4318
    example: `"cannot use insert() with string"`
 
4319
    @throw std::domain_error if @a pos is not an iterator of *this; example:
 
4320
    `"iterator does not fit current value"`
 
4321
    @throw std::domain_error if @a first and @a last do not belong to the same
 
4322
    JSON value; example: `"iterators do not fit"`
 
4323
    @throw std::domain_error if @a first or @a last are iterators into
 
4324
    container for which insert is called; example: `"passed iterators may not
 
4325
    belong to container"`
 
4326
 
 
4327
    @return iterator pointing to the first element inserted, or @a pos if
 
4328
    `first==last`
 
4329
 
 
4330
    @complexity Linear in `std::distance(first, last)` plus linear in the
 
4331
    distance between @a pos and end of the container.
 
4332
 
 
4333
    @liveexample{The example shows how insert is used.,insert__range}
 
4334
 
 
4335
    @since version 1.0.0
 
4336
    */
 
4337
    iterator insert(const_iterator pos, const_iterator first, const_iterator last)
 
4338
    {
 
4339
        // insert only works for arrays
 
4340
        if (not is_array())
 
4341
        {
 
4342
            throw std::domain_error("cannot use insert() with " + type_name());
 
4343
        }
 
4344
 
 
4345
        // check if iterator pos fits to this JSON value
 
4346
        if (pos.m_object != this)
 
4347
        {
 
4348
            throw std::domain_error("iterator does not fit current value");
 
4349
        }
 
4350
 
 
4351
        if (first.m_object != last.m_object)
 
4352
        {
 
4353
            throw std::domain_error("iterators do not fit");
 
4354
        }
 
4355
 
 
4356
        if (first.m_object == this or last.m_object == this)
 
4357
        {
 
4358
            throw std::domain_error("passed iterators may not belong to container");
 
4359
        }
 
4360
 
 
4361
        // insert to array and return iterator
 
4362
        iterator result(this);
 
4363
        result.m_it.array_iterator = m_value.array->insert(
 
4364
                                         pos.m_it.array_iterator,
 
4365
                                         first.m_it.array_iterator,
 
4366
                                         last.m_it.array_iterator);
 
4367
        return result;
 
4368
    }
 
4369
 
 
4370
    /*!
 
4371
    @brief inserts elements
 
4372
 
 
4373
    Inserts elements from initializer list @a ilist before iterator @a pos.
 
4374
 
 
4375
    @param[in] pos iterator before which the content will be inserted; may be
 
4376
    the end() iterator
 
4377
    @param[in] ilist initializer list to insert the values from
 
4378
 
 
4379
    @throw std::domain_error if called on JSON values other than arrays;
 
4380
    example: `"cannot use insert() with string"`
 
4381
    @throw std::domain_error if @a pos is not an iterator of *this; example:
 
4382
    `"iterator does not fit current value"`
 
4383
 
 
4384
    @return iterator pointing to the first element inserted, or @a pos if
 
4385
    `ilist` is empty
 
4386
 
 
4387
    @complexity Linear in `ilist.size()` plus linear in the distance between @a
 
4388
    pos and end of the container.
 
4389
 
 
4390
    @liveexample{The example shows how insert is used.,insert__ilist}
 
4391
 
 
4392
    @since version 1.0.0
 
4393
    */
 
4394
    iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
 
4395
    {
 
4396
        // insert only works for arrays
 
4397
        if (not is_array())
 
4398
        {
 
4399
            throw std::domain_error("cannot use insert() with " + type_name());
 
4400
        }
 
4401
 
 
4402
        // check if iterator pos fits to this JSON value
 
4403
        if (pos.m_object != this)
 
4404
        {
 
4405
            throw std::domain_error("iterator does not fit current value");
 
4406
        }
 
4407
 
 
4408
        // insert to array and return iterator
 
4409
        iterator result(this);
 
4410
        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
 
4411
        return result;
 
4412
    }
 
4413
 
 
4414
    /*!
 
4415
    @brief exchanges the values
 
4416
 
 
4417
    Exchanges the contents of the JSON value with those of @a other. Does not
 
4418
    invoke any move, copy, or swap operations on individual elements. All
 
4419
    iterators and references remain valid. The past-the-end iterator is
 
4420
    invalidated.
 
4421
 
 
4422
    @param[in,out] other JSON value to exchange the contents with
 
4423
 
 
4424
    @complexity Constant.
 
4425
 
 
4426
    @liveexample{The example below shows how JSON arrays can be
 
4427
    swapped.,swap__reference}
 
4428
 
 
4429
    @since version 1.0.0
 
4430
    */
 
4431
    void swap(reference other) noexcept (
 
4432
        std::is_nothrow_move_constructible<value_t>::value and
 
4433
        std::is_nothrow_move_assignable<value_t>::value and
 
4434
        std::is_nothrow_move_constructible<json_value>::value and
 
4435
        std::is_nothrow_move_assignable<json_value>::value
 
4436
    )
 
4437
    {
 
4438
        std::swap(m_type, other.m_type);
 
4439
        std::swap(m_value, other.m_value);
 
4440
    }
 
4441
 
 
4442
    /*!
 
4443
    @brief exchanges the values
 
4444
 
 
4445
    Exchanges the contents of a JSON array with those of @a other. Does not
 
4446
    invoke any move, copy, or swap operations on individual elements. All
 
4447
    iterators and references remain valid. The past-the-end iterator is
 
4448
    invalidated.
 
4449
 
 
4450
    @param[in,out] other array to exchange the contents with
 
4451
 
 
4452
    @throw std::domain_error when JSON value is not an array; example: `"cannot
 
4453
    use swap() with string"`
 
4454
 
 
4455
    @complexity Constant.
 
4456
 
 
4457
    @liveexample{The example below shows how JSON values can be
 
4458
    swapped.,swap__array_t}
 
4459
 
 
4460
    @since version 1.0.0
 
4461
    */
 
4462
    void swap(array_t& other)
 
4463
    {
 
4464
        // swap only works for arrays
 
4465
        if (is_array())
 
4466
        {
 
4467
            std::swap(*(m_value.array), other);
 
4468
        }
 
4469
        else
 
4470
        {
 
4471
            throw std::domain_error("cannot use swap() with " + type_name());
 
4472
        }
 
4473
    }
 
4474
 
 
4475
    /*!
 
4476
    @brief exchanges the values
 
4477
 
 
4478
    Exchanges the contents of a JSON object with those of @a other. Does not
 
4479
    invoke any move, copy, or swap operations on individual elements. All
 
4480
    iterators and references remain valid. The past-the-end iterator is
 
4481
    invalidated.
 
4482
 
 
4483
    @param[in,out] other object to exchange the contents with
 
4484
 
 
4485
    @throw std::domain_error when JSON value is not an object; example:
 
4486
    `"cannot use swap() with string"`
 
4487
 
 
4488
    @complexity Constant.
 
4489
 
 
4490
    @liveexample{The example below shows how JSON values can be
 
4491
    swapped.,swap__object_t}
 
4492
 
 
4493
    @since version 1.0.0
 
4494
    */
 
4495
    void swap(object_t& other)
 
4496
    {
 
4497
        // swap only works for objects
 
4498
        if (is_object())
 
4499
        {
 
4500
            std::swap(*(m_value.object), other);
 
4501
        }
 
4502
        else
 
4503
        {
 
4504
            throw std::domain_error("cannot use swap() with " + type_name());
 
4505
        }
 
4506
    }
 
4507
 
 
4508
    /*!
 
4509
    @brief exchanges the values
 
4510
 
 
4511
    Exchanges the contents of a JSON string with those of @a other. Does not
 
4512
    invoke any move, copy, or swap operations on individual elements. All
 
4513
    iterators and references remain valid. The past-the-end iterator is
 
4514
    invalidated.
 
4515
 
 
4516
    @param[in,out] other string to exchange the contents with
 
4517
 
 
4518
    @throw std::domain_error when JSON value is not a string; example: `"cannot
 
4519
    use swap() with boolean"`
 
4520
 
 
4521
    @complexity Constant.
 
4522
 
 
4523
    @liveexample{The example below shows how JSON values can be
 
4524
    swapped.,swap__string_t}
 
4525
 
 
4526
    @since version 1.0.0
 
4527
    */
 
4528
    void swap(string_t& other)
 
4529
    {
 
4530
        // swap only works for strings
 
4531
        if (is_string())
 
4532
        {
 
4533
            std::swap(*(m_value.string), other);
 
4534
        }
 
4535
        else
 
4536
        {
 
4537
            throw std::domain_error("cannot use swap() with " + type_name());
 
4538
        }
 
4539
    }
 
4540
 
 
4541
    /// @}
 
4542
 
 
4543
 
 
4544
    //////////////////////////////////////////
 
4545
    // lexicographical comparison operators //
 
4546
    //////////////////////////////////////////
 
4547
 
 
4548
    /// @name lexicographical comparison operators
 
4549
    /// @{
 
4550
 
 
4551
  private:
 
4552
    /*!
 
4553
    @brief comparison operator for JSON types
 
4554
 
 
4555
    Returns an ordering that is similar to Python:
 
4556
    - order: null < boolean < number < object < array < string
 
4557
    - furthermore, each type is not smaller than itself
 
4558
 
 
4559
    @since version 1.0.0
 
4560
    */
 
4561
    friend bool operator<(const value_t lhs, const value_t rhs)
 
4562
    {
 
4563
        static constexpr std::array<uint8_t, 7> order = {{
 
4564
                0, // null
 
4565
                3, // object
 
4566
                4, // array
 
4567
                5, // string
 
4568
                1, // boolean
 
4569
                2, // integer
 
4570
                2  // float
 
4571
            }
 
4572
        };
 
4573
 
 
4574
        // discarded values are not comparable
 
4575
        if (lhs == value_t::discarded or rhs == value_t::discarded)
 
4576
        {
 
4577
            return false;
 
4578
        }
 
4579
 
 
4580
        return order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
 
4581
    }
 
4582
 
 
4583
  public:
 
4584
    /*!
 
4585
    @brief comparison: equal
 
4586
 
 
4587
    Compares two JSON values for equality according to the following rules:
 
4588
    - Two JSON values are equal if (1) they are from the same type and (2)
 
4589
      their stored values are the same.
 
4590
    - Integer and floating-point numbers are automatically converted before
 
4591
      comparison. Floating-point numbers are compared indirectly: two
 
4592
      floating-point numbers `f1` and `f2` are considered equal if neither
 
4593
      `f1 > f2` nor `f2 > f1` holds.
 
4594
    - Two JSON null values are equal.
 
4595
 
 
4596
    @param[in] lhs  first JSON value to consider
 
4597
    @param[in] rhs  second JSON value to consider
 
4598
    @return whether the values @a lhs and @a rhs are equal
 
4599
 
 
4600
    @complexity Linear.
 
4601
 
 
4602
    @liveexample{The example demonstrates comparing several JSON
 
4603
    types.,operator__equal}
 
4604
 
 
4605
    @since version 1.0.0
 
4606
    */
 
4607
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
 
4608
    {
 
4609
        const auto lhs_type = lhs.type();
 
4610
        const auto rhs_type = rhs.type();
 
4611
 
 
4612
        if (lhs_type == rhs_type)
 
4613
        {
 
4614
            switch (lhs_type)
 
4615
            {
 
4616
                case value_t::array:
 
4617
                    return *lhs.m_value.array == *rhs.m_value.array;
 
4618
                case value_t::object:
 
4619
                    return *lhs.m_value.object == *rhs.m_value.object;
 
4620
                case value_t::null:
 
4621
                    return true;
 
4622
                case value_t::string:
 
4623
                    return *lhs.m_value.string == *rhs.m_value.string;
 
4624
                case value_t::boolean:
 
4625
                    return lhs.m_value.boolean == rhs.m_value.boolean;
 
4626
                case value_t::number_integer:
 
4627
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
 
4628
                case value_t::number_float:
 
4629
                    return approx(lhs.m_value.number_float, rhs.m_value.number_float);
 
4630
                default:
 
4631
                    return false;
 
4632
            }
 
4633
        }
 
4634
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 
4635
        {
 
4636
            return approx(static_cast<number_float_t>(lhs.m_value.number_integer),
 
4637
                          rhs.m_value.number_float);
 
4638
        }
 
4639
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
 
4640
        {
 
4641
            return approx(lhs.m_value.number_float,
 
4642
                          static_cast<number_float_t>(rhs.m_value.number_integer));
 
4643
        }
 
4644
        return false;
 
4645
    }
 
4646
 
 
4647
    /*!
 
4648
    @brief comparison: equal
 
4649
 
 
4650
    The functions compares the given JSON value against a null pointer. As the
 
4651
    null pointer can be used to initialize a JSON value to null, a comparison
 
4652
    of JSON value @a v with a null pointer should be equivalent to call
 
4653
    `v.is_null()`.
 
4654
 
 
4655
    @param[in] v  JSON value to consider
 
4656
    @return whether @a v is null
 
4657
 
 
4658
    @complexity Constant.
 
4659
 
 
4660
    @liveexample{The example compares several JSON types to the null pointer.
 
4661
    ,operator__equal__nullptr_t}
 
4662
 
 
4663
    @since version 1.0.0
 
4664
    */
 
4665
    friend bool operator==(const_reference v, std::nullptr_t) noexcept
 
4666
    {
 
4667
        return v.is_null();
 
4668
    }
 
4669
 
 
4670
    /*!
 
4671
    @brief comparison: equal
 
4672
    @copydoc operator==(const_reference, std::nullptr_t)
 
4673
    */
 
4674
    friend bool operator==(std::nullptr_t, const_reference v) noexcept
 
4675
    {
 
4676
        return v.is_null();
 
4677
    }
 
4678
 
 
4679
    /*!
 
4680
    @brief comparison: not equal
 
4681
 
 
4682
    Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
 
4683
 
 
4684
    @param[in] lhs  first JSON value to consider
 
4685
    @param[in] rhs  second JSON value to consider
 
4686
    @return whether the values @a lhs and @a rhs are not equal
 
4687
 
 
4688
    @complexity Linear.
 
4689
 
 
4690
    @liveexample{The example demonstrates comparing several JSON
 
4691
    types.,operator__notequal}
 
4692
 
 
4693
    @since version 1.0.0
 
4694
    */
 
4695
    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
 
4696
    {
 
4697
        return not (lhs == rhs);
 
4698
    }
 
4699
 
 
4700
    /*!
 
4701
    @brief comparison: not equal
 
4702
 
 
4703
    The functions compares the given JSON value against a null pointer. As the
 
4704
    null pointer can be used to initialize a JSON value to null, a comparison
 
4705
    of JSON value @a v with a null pointer should be equivalent to call
 
4706
    `not v.is_null()`.
 
4707
 
 
4708
    @param[in] v  JSON value to consider
 
4709
    @return whether @a v is not null
 
4710
 
 
4711
    @complexity Constant.
 
4712
 
 
4713
    @liveexample{The example compares several JSON types to the null pointer.
 
4714
    ,operator__notequal__nullptr_t}
 
4715
 
 
4716
    @since version 1.0.0
 
4717
    */
 
4718
    friend bool operator!=(const_reference v, std::nullptr_t) noexcept
 
4719
    {
 
4720
        return not v.is_null();
 
4721
    }
 
4722
 
 
4723
    /*!
 
4724
    @brief comparison: not equal
 
4725
    @copydoc operator!=(const_reference, std::nullptr_t)
 
4726
    */
 
4727
    friend bool operator!=(std::nullptr_t, const_reference v) noexcept
 
4728
    {
 
4729
        return not v.is_null();
 
4730
    }
 
4731
 
 
4732
    /*!
 
4733
    @brief comparison: less than
 
4734
 
 
4735
    Compares whether one JSON value @a lhs is less than another JSON value @a
 
4736
    rhs according to the following rules:
 
4737
    - If @a lhs and @a rhs have the same type, the values are compared using
 
4738
      the default `<` operator.
 
4739
    - Integer and floating-point numbers are automatically converted before
 
4740
      comparison
 
4741
    - In case @a lhs and @a rhs have different types, the values are ignored
 
4742
      and the order of the types is considered, see
 
4743
      @ref operator<(const value_t, const value_t).
 
4744
 
 
4745
    @param[in] lhs  first JSON value to consider
 
4746
    @param[in] rhs  second JSON value to consider
 
4747
    @return whether @a lhs is less than @a rhs
 
4748
 
 
4749
    @complexity Linear.
 
4750
 
 
4751
    @liveexample{The example demonstrates comparing several JSON
 
4752
    types.,operator__less}
 
4753
 
 
4754
    @since version 1.0.0
 
4755
    */
 
4756
    friend bool operator<(const_reference lhs, const_reference rhs) noexcept
 
4757
    {
 
4758
        const auto lhs_type = lhs.type();
 
4759
        const auto rhs_type = rhs.type();
 
4760
 
 
4761
        if (lhs_type == rhs_type)
 
4762
        {
 
4763
            switch (lhs_type)
 
4764
            {
 
4765
                case value_t::array:
 
4766
                    return *lhs.m_value.array < *rhs.m_value.array;
 
4767
                case value_t::object:
 
4768
                    return *lhs.m_value.object < *rhs.m_value.object;
 
4769
                case value_t::null:
 
4770
                    return false;
 
4771
                case value_t::string:
 
4772
                    return *lhs.m_value.string < *rhs.m_value.string;
 
4773
                case value_t::boolean:
 
4774
                    return lhs.m_value.boolean < rhs.m_value.boolean;
 
4775
                case value_t::number_integer:
 
4776
                    return lhs.m_value.number_integer < rhs.m_value.number_integer;
 
4777
                case value_t::number_float:
 
4778
                    return lhs.m_value.number_float < rhs.m_value.number_float;
 
4779
                default:
 
4780
                    return false;
 
4781
            }
 
4782
        }
 
4783
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 
4784
        {
 
4785
            return static_cast<number_float_t>(lhs.m_value.number_integer) <
 
4786
                   rhs.m_value.number_float;
 
4787
        }
 
4788
        else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
 
4789
        {
 
4790
            return lhs.m_value.number_float <
 
4791
                   static_cast<number_float_t>(rhs.m_value.number_integer);
 
4792
        }
 
4793
 
 
4794
        // We only reach this line if we cannot compare values. In that case,
 
4795
        // we compare types. Note we have to call the operator explicitly,
 
4796
        // because MSVC has problems otherwise.
 
4797
        return operator<(lhs_type, rhs_type);
 
4798
    }
 
4799
 
 
4800
    /*!
 
4801
    @brief comparison: less than or equal
 
4802
 
 
4803
    Compares whether one JSON value @a lhs is less than or equal to another
 
4804
    JSON value by calculating `not (rhs < lhs)`.
 
4805
 
 
4806
    @param[in] lhs  first JSON value to consider
 
4807
    @param[in] rhs  second JSON value to consider
 
4808
    @return whether @a lhs is less than or equal to @a rhs
 
4809
 
 
4810
    @complexity Linear.
 
4811
 
 
4812
    @liveexample{The example demonstrates comparing several JSON
 
4813
    types.,operator__greater}
 
4814
 
 
4815
    @since version 1.0.0
 
4816
    */
 
4817
    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
 
4818
    {
 
4819
        return not (rhs < lhs);
 
4820
    }
 
4821
 
 
4822
    /*!
 
4823
    @brief comparison: greater than
 
4824
 
 
4825
    Compares whether one JSON value @a lhs is greater than another
 
4826
    JSON value by calculating `not (lhs <= rhs)`.
 
4827
 
 
4828
    @param[in] lhs  first JSON value to consider
 
4829
    @param[in] rhs  second JSON value to consider
 
4830
    @return whether @a lhs is greater than to @a rhs
 
4831
 
 
4832
    @complexity Linear.
 
4833
 
 
4834
    @liveexample{The example demonstrates comparing several JSON
 
4835
    types.,operator__lessequal}
 
4836
 
 
4837
    @since version 1.0.0
 
4838
    */
 
4839
    friend bool operator>(const_reference lhs, const_reference rhs) noexcept
 
4840
    {
 
4841
        return not (lhs <= rhs);
 
4842
    }
 
4843
 
 
4844
    /*!
 
4845
    @brief comparison: greater than or equal
 
4846
 
 
4847
    Compares whether one JSON value @a lhs is greater than or equal to another
 
4848
    JSON value by calculating `not (lhs < rhs)`.
 
4849
 
 
4850
    @param[in] lhs  first JSON value to consider
 
4851
    @param[in] rhs  second JSON value to consider
 
4852
    @return whether @a lhs is greater than or equal to @a rhs
 
4853
 
 
4854
    @complexity Linear.
 
4855
 
 
4856
    @liveexample{The example demonstrates comparing several JSON
 
4857
    types.,operator__greaterequal}
 
4858
 
 
4859
    @since version 1.0.0
 
4860
    */
 
4861
    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
 
4862
    {
 
4863
        return not (lhs < rhs);
 
4864
    }
 
4865
 
 
4866
    /// @}
 
4867
 
 
4868
 
 
4869
    ///////////////////
 
4870
    // serialization //
 
4871
    ///////////////////
 
4872
 
 
4873
    /// @name serialization
 
4874
    /// @{
 
4875
 
 
4876
    /*!
 
4877
    @brief serialize to stream
 
4878
 
 
4879
    Serialize the given JSON value @a j to the output stream @a o. The JSON
 
4880
    value will be serialized using the @ref dump member function. The
 
4881
    indentation of the output can be controlled with the member variable
 
4882
    `width` of the output stream @a o. For instance, using the manipulator
 
4883
    `std::setw(4)` on @a o sets the indentation level to `4` and the
 
4884
    serialization result is the same as calling `dump(4)`.
 
4885
 
 
4886
    @param[in,out] o  stream to serialize to
 
4887
    @param[in] j  JSON value to serialize
 
4888
 
 
4889
    @return the stream @a o
 
4890
 
 
4891
    @complexity Linear.
 
4892
 
 
4893
    @liveexample{The example below shows the serialization with different
 
4894
    parameters to `width` to adjust the indentation level.,operator_serialize}
 
4895
 
 
4896
    @since version 1.0.0
 
4897
    */
 
4898
    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
 
4899
    {
 
4900
        // read width member and use it as indentation parameter if nonzero
 
4901
        const bool pretty_print = (o.width() > 0);
 
4902
        const auto indentation = (pretty_print ? o.width() : 0);
 
4903
 
 
4904
        // reset width to 0 for subsequent calls to this stream
 
4905
        o.width(0);
 
4906
 
 
4907
        // do the actual serialization
 
4908
        j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
 
4909
        return o;
 
4910
    }
 
4911
 
 
4912
    /*!
 
4913
    @brief serialize to stream
 
4914
    @copydoc operator<<(std::ostream&, const basic_json&)
 
4915
    */
 
4916
    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
 
4917
    {
 
4918
        return o << j;
 
4919
    }
 
4920
 
 
4921
    /// @}
 
4922
 
 
4923
 
 
4924
    /////////////////////
 
4925
    // deserialization //
 
4926
    /////////////////////
 
4927
 
 
4928
    /// @name deserialization
 
4929
    /// @{
 
4930
 
 
4931
    /*!
 
4932
    @brief deserialize from string
 
4933
 
 
4934
    @param[in] s  string to read a serialized JSON value from
 
4935
    @param[in] cb a parser callback function of type @ref parser_callback_t
 
4936
    which is used to control the deserialization by filtering unwanted values
 
4937
    (optional)
 
4938
 
 
4939
    @return result of the deserialization
 
4940
 
 
4941
    @complexity Linear in the length of the input. The parser is a predictive
 
4942
    LL(1) parser. The complexity can be higher if the parser callback function
 
4943
    @a cb has a super-linear complexity.
 
4944
 
 
4945
    @note A UTF-8 byte order mark is silently ignored.
 
4946
 
 
4947
    @liveexample{The example below demonstrates the parse function with and
 
4948
    without callback function.,parse__string__parser_callback_t}
 
4949
 
 
4950
    @sa @ref parse(std::istream&, parser_callback_t) for a version that reads
 
4951
    from an input stream
 
4952
 
 
4953
    @since version 1.0.0
 
4954
    */
 
4955
    static basic_json parse(const string_t& s, parser_callback_t cb = nullptr)
 
4956
    {
 
4957
        return parser(s, cb).parse();
 
4958
    }
 
4959
 
 
4960
    /*!
 
4961
    @brief deserialize from stream
 
4962
 
 
4963
    @param[in,out] i  stream to read a serialized JSON value from
 
4964
    @param[in] cb a parser callback function of type @ref parser_callback_t
 
4965
    which is used to control the deserialization by filtering unwanted values
 
4966
    (optional)
 
4967
 
 
4968
    @return result of the deserialization
 
4969
 
 
4970
    @complexity Linear in the length of the input. The parser is a predictive
 
4971
    LL(1) parser. The complexity can be higher if the parser callback function
 
4972
    @a cb has a super-linear complexity.
 
4973
 
 
4974
    @note A UTF-8 byte order mark is silently ignored.
 
4975
 
 
4976
    @liveexample{The example below demonstrates the parse function with and
 
4977
    without callback function.,parse__istream__parser_callback_t}
 
4978
 
 
4979
    @sa @ref parse(const string_t&, parser_callback_t) for a version that reads
 
4980
    from a string
 
4981
 
 
4982
    @since version 1.0.0
 
4983
    */
 
4984
    static basic_json parse(std::istream& i, parser_callback_t cb = nullptr)
 
4985
    {
 
4986
        return parser(i, cb).parse();
 
4987
    }
 
4988
 
 
4989
    /*!
 
4990
    @copydoc parse(std::istream&, parser_callback_t)
 
4991
    */
 
4992
    static basic_json parse(std::istream&& i, parser_callback_t cb = nullptr)
 
4993
    {
 
4994
        return parser(i, cb).parse();
 
4995
    }
 
4996
 
 
4997
    /*!
 
4998
    @brief deserialize from stream
 
4999
 
 
5000
    Deserializes an input stream to a JSON value.
 
5001
 
 
5002
    @param[in,out] i  input stream to read a serialized JSON value from
 
5003
    @param[in,out] j  JSON value to write the deserialized input to
 
5004
 
 
5005
    @throw std::invalid_argument in case of parse errors
 
5006
 
 
5007
    @complexity Linear in the length of the input. The parser is a predictive
 
5008
    LL(1) parser.
 
5009
 
 
5010
    @note A UTF-8 byte order mark is silently ignored.
 
5011
 
 
5012
    @liveexample{The example below shows how a JSON value is constructed by
 
5013
    reading a serialization from a stream.,operator_deserialize}
 
5014
 
 
5015
    @sa parse(std::istream&, parser_callback_t) for a variant with a parser
 
5016
    callback function to filter values while parsing
 
5017
 
 
5018
    @since version 1.0.0
 
5019
    */
 
5020
    friend std::istream& operator<<(basic_json& j, std::istream& i)
 
5021
    {
 
5022
        j = parser(i).parse();
 
5023
        return i;
 
5024
    }
 
5025
 
 
5026
    /*!
 
5027
    @brief deserialize from stream
 
5028
    @copydoc operator<<(basic_json&, std::istream&)
 
5029
    */
 
5030
    friend std::istream& operator>>(std::istream& i, basic_json& j)
 
5031
    {
 
5032
        j = parser(i).parse();
 
5033
        return i;
 
5034
    }
 
5035
 
 
5036
    /// @}
 
5037
 
 
5038
 
 
5039
  private:
 
5040
    ///////////////////////////
 
5041
    // convenience functions //
 
5042
    ///////////////////////////
 
5043
 
 
5044
    /// return the type as string
 
5045
    string_t type_name() const
 
5046
    {
 
5047
        switch (m_type)
 
5048
        {
 
5049
            case value_t::null:
 
5050
                return "null";
 
5051
            case value_t::object:
 
5052
                return "object";
 
5053
            case value_t::array:
 
5054
                return "array";
 
5055
            case value_t::string:
 
5056
                return "string";
 
5057
            case value_t::boolean:
 
5058
                return "boolean";
 
5059
            case value_t::discarded:
 
5060
                return "discarded";
 
5061
            default:
 
5062
                return "number";
 
5063
        }
 
5064
    }
 
5065
 
 
5066
    /*!
 
5067
    @brief calculates the extra space to escape a JSON string
 
5068
 
 
5069
    @param[in] s  the string to escape
 
5070
    @return the number of characters required to escape string @a s
 
5071
 
 
5072
    @complexity Linear in the length of string @a s.
 
5073
    */
 
5074
    static std::size_t extra_space(const string_t& s) noexcept
 
5075
    {
 
5076
        std::size_t result = 0;
 
5077
 
 
5078
        for (const auto& c : s)
 
5079
        {
 
5080
            switch (c)
 
5081
            {
 
5082
                case '"':
 
5083
                case '\\':
 
5084
                case '\b':
 
5085
                case '\f':
 
5086
                case '\n':
 
5087
                case '\r':
 
5088
                case '\t':
 
5089
                {
 
5090
                    // from c (1 byte) to \x (2 bytes)
 
5091
                    result += 1;
 
5092
                    break;
 
5093
                }
 
5094
 
 
5095
                default:
 
5096
                {
 
5097
                    if (c >= 0x00 and c <= 0x1f)
 
5098
                    {
 
5099
                        // from c (1 byte) to \uxxxx (6 bytes)
 
5100
                        result += 5;
 
5101
                    }
 
5102
                    break;
 
5103
                }
 
5104
            }
 
5105
        }
 
5106
 
 
5107
        return result;
 
5108
    }
 
5109
 
 
5110
    /*!
 
5111
    @brief escape a string
 
5112
 
 
5113
    Escape a string by replacing certain special characters by a sequence of an
 
5114
    escape character (backslash) and another character and other control
 
5115
    characters by a sequence of "\u" followed by a four-digit hex
 
5116
    representation.
 
5117
 
 
5118
    @param[in] s  the string to escape
 
5119
    @return  the escaped string
 
5120
 
 
5121
    @complexity Linear in the length of string @a s.
 
5122
    */
 
5123
    static string_t escape_string(const string_t& s) noexcept
 
5124
    {
 
5125
        const auto space = extra_space(s);
 
5126
        if (space == 0)
 
5127
        {
 
5128
            return s;
 
5129
        }
 
5130
 
 
5131
        // create a result string of necessary size
 
5132
        string_t result(s.size() + space, '\\');
 
5133
        std::size_t pos = 0;
 
5134
 
 
5135
        for (const auto& c : s)
 
5136
        {
 
5137
            switch (c)
 
5138
            {
 
5139
                // quotation mark (0x22)
 
5140
                case '"':
 
5141
                {
 
5142
                    result[pos + 1] = '"';
 
5143
                    pos += 2;
 
5144
                    break;
 
5145
                }
 
5146
 
 
5147
                // reverse solidus (0x5c)
 
5148
                case '\\':
 
5149
                {
 
5150
                    // nothing to change
 
5151
                    pos += 2;
 
5152
                    break;
 
5153
                }
 
5154
 
 
5155
                // backspace (0x08)
 
5156
                case '\b':
 
5157
                {
 
5158
                    result[pos + 1] = 'b';
 
5159
                    pos += 2;
 
5160
                    break;
 
5161
                }
 
5162
 
 
5163
                // formfeed (0x0c)
 
5164
                case '\f':
 
5165
                {
 
5166
                    result[pos + 1] = 'f';
 
5167
                    pos += 2;
 
5168
                    break;
 
5169
                }
 
5170
 
 
5171
                // newline (0x0a)
 
5172
                case '\n':
 
5173
                {
 
5174
                    result[pos + 1] = 'n';
 
5175
                    pos += 2;
 
5176
                    break;
 
5177
                }
 
5178
 
 
5179
                // carriage return (0x0d)
 
5180
                case '\r':
 
5181
                {
 
5182
                    result[pos + 1] = 'r';
 
5183
                    pos += 2;
 
5184
                    break;
 
5185
                }
 
5186
 
 
5187
                // horizontal tab (0x09)
 
5188
                case '\t':
 
5189
                {
 
5190
                    result[pos + 1] = 't';
 
5191
                    pos += 2;
 
5192
                    break;
 
5193
                }
 
5194
 
 
5195
                default:
 
5196
                {
 
5197
                    if (c >= 0x00 and c <= 0x1f)
 
5198
                    {
 
5199
                        // convert a number 0..15 to its hex representation (0..f)
 
5200
                        auto hexify = [](const char v) -> char
 
5201
                        {
 
5202
                            return (v < 10) ? ('0' + v) : ('a' + v - 10);
 
5203
                        };
 
5204
 
 
5205
                        // print character c as \uxxxx
 
5206
                        for (const char m :
 
5207
                    { 'u', '0', '0', hexify(c >> 4), hexify(c & 0x0f)
 
5208
                        })
 
5209
                        {
 
5210
                            result[++pos] = m;
 
5211
                        }
 
5212
 
 
5213
                        ++pos;
 
5214
                    }
 
5215
                    else
 
5216
                    {
 
5217
                        // all other characters are added as-is
 
5218
                        result[pos++] = c;
 
5219
                    }
 
5220
                    break;
 
5221
                }
 
5222
            }
 
5223
        }
 
5224
 
 
5225
        return result;
 
5226
    }
 
5227
 
 
5228
    /*!
 
5229
    @brief internal implementation of the serialization function
 
5230
 
 
5231
    This function is called by the public member function dump and organizes
 
5232
    the serializaion internally. The indentation level is propagated as
 
5233
    additional parameter. In case of arrays and objects, the function is called
 
5234
    recursively. Note that
 
5235
 
 
5236
    - strings and object keys are escaped using escape_string()
 
5237
    - integer numbers are converted implictly via operator<<
 
5238
    - floating-point numbers are converted to a string using "%g" format
 
5239
 
 
5240
    @param[out] o              stream to write to
 
5241
    @param[in] pretty_print    whether the output shall be pretty-printed
 
5242
    @param[in] indent_step     the indent level
 
5243
    @param[in] current_indent  the current indent level (only used internally)
 
5244
    */
 
5245
    void dump(std::ostream& o,
 
5246
              const bool pretty_print,
 
5247
              const unsigned int indent_step,
 
5248
              const unsigned int current_indent = 0) const
 
5249
    {
 
5250
        // variable to hold indentation for recursive calls
 
5251
        unsigned int new_indent = current_indent;
 
5252
 
 
5253
        switch (m_type)
 
5254
        {
 
5255
            case value_t::object:
 
5256
            {
 
5257
                if (m_value.object->empty())
 
5258
                {
 
5259
                    o << "{}";
 
5260
                    return;
 
5261
                }
 
5262
 
 
5263
                o << "{";
 
5264
 
 
5265
                // increase indentation
 
5266
                if (pretty_print)
 
5267
                {
 
5268
                    new_indent += indent_step;
 
5269
                    o << "\n";
 
5270
                }
 
5271
 
 
5272
                for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
 
5273
                {
 
5274
                    if (i != m_value.object->cbegin())
 
5275
                    {
 
5276
                        o << (pretty_print ? ",\n" : ",");
 
5277
                    }
 
5278
                    o << string_t(new_indent, ' ') << "\""
 
5279
                      << escape_string(i->first) << "\":"
 
5280
                      << (pretty_print ? " " : "");
 
5281
                    i->second.dump(o, pretty_print, indent_step, new_indent);
 
5282
                }
 
5283
 
 
5284
                // decrease indentation
 
5285
                if (pretty_print)
 
5286
                {
 
5287
                    new_indent -= indent_step;
 
5288
                    o << "\n";
 
5289
                }
 
5290
 
 
5291
                o << string_t(new_indent, ' ') + "}";
 
5292
                return;
 
5293
            }
 
5294
 
 
5295
            case value_t::array:
 
5296
            {
 
5297
                if (m_value.array->empty())
 
5298
                {
 
5299
                    o << "[]";
 
5300
                    return;
 
5301
                }
 
5302
 
 
5303
                o << "[";
 
5304
 
 
5305
                // increase indentation
 
5306
                if (pretty_print)
 
5307
                {
 
5308
                    new_indent += indent_step;
 
5309
                    o << "\n";
 
5310
                }
 
5311
 
 
5312
                for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
 
5313
                {
 
5314
                    if (i != m_value.array->cbegin())
 
5315
                    {
 
5316
                        o << (pretty_print ? ",\n" : ",");
 
5317
                    }
 
5318
                    o << string_t(new_indent, ' ');
 
5319
                    i->dump(o, pretty_print, indent_step, new_indent);
 
5320
                }
 
5321
 
 
5322
                // decrease indentation
 
5323
                if (pretty_print)
 
5324
                {
 
5325
                    new_indent -= indent_step;
 
5326
                    o << "\n";
 
5327
                }
 
5328
 
 
5329
                o << string_t(new_indent, ' ') << "]";
 
5330
                return;
 
5331
            }
 
5332
 
 
5333
            case value_t::string:
 
5334
            {
 
5335
                o << string_t("\"") << escape_string(*m_value.string) << "\"";
 
5336
                return;
 
5337
            }
 
5338
 
 
5339
            case value_t::boolean:
 
5340
            {
 
5341
                o << (m_value.boolean ? "true" : "false");
 
5342
                return;
 
5343
            }
 
5344
 
 
5345
            case value_t::number_integer:
 
5346
            {
 
5347
                o << m_value.number_integer;
 
5348
                return;
 
5349
            }
 
5350
 
 
5351
            case value_t::number_float:
 
5352
            {
 
5353
                // 15 digits of precision allows round-trip IEEE 754
 
5354
                // string->double->string; to be safe, we read this value from
 
5355
                // std::numeric_limits<number_float_t>::digits10
 
5356
                o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
 
5357
                return;
 
5358
            }
 
5359
 
 
5360
            case value_t::discarded:
 
5361
            {
 
5362
                o << "<discarded>";
 
5363
                return;
 
5364
            }
 
5365
 
 
5366
            case value_t::null:
 
5367
            {
 
5368
                o << "null";
 
5369
                return;
 
5370
            }
 
5371
        }
 
5372
    }
 
5373
 
 
5374
  private:
 
5375
    //////////////////////
 
5376
    // member variables //
 
5377
    //////////////////////
 
5378
 
 
5379
    /// the type of the current element
 
5380
    value_t m_type = value_t::null;
 
5381
 
 
5382
    /// the value of the current element
 
5383
    json_value m_value = {};
 
5384
 
 
5385
 
 
5386
  private:
 
5387
    ///////////////
 
5388
    // iterators //
 
5389
    ///////////////
 
5390
 
 
5391
    /*!
 
5392
    @brief an iterator for primitive JSON types
 
5393
 
 
5394
    This class models an iterator for primitive JSON types (boolean, number,
 
5395
    string). It's only purpose is to allow the iterator/const_iterator classes
 
5396
    to "iterate" over primitive values. Internally, the iterator is modeled by
 
5397
    a `difference_type` variable. Value begin_value (`0`) models the begin,
 
5398
    end_value (`1`) models past the end.
 
5399
    */
 
5400
    class primitive_iterator_t
 
5401
    {
 
5402
      public:
 
5403
        /// set iterator to a defined beginning
 
5404
        void set_begin()
 
5405
        {
 
5406
            m_it = begin_value;
 
5407
        }
 
5408
 
 
5409
        /// set iterator to a defined past the end
 
5410
        void set_end()
 
5411
        {
 
5412
            m_it = end_value;
 
5413
        }
 
5414
 
 
5415
        /// return whether the iterator can be dereferenced
 
5416
        bool is_begin() const
 
5417
        {
 
5418
            return (m_it == begin_value);
 
5419
        }
 
5420
 
 
5421
        /// return whether the iterator is at end
 
5422
        bool is_end() const
 
5423
        {
 
5424
            return (m_it == end_value);
 
5425
        }
 
5426
 
 
5427
        /// return reference to the value to change and compare
 
5428
        operator difference_type& ()
 
5429
        {
 
5430
            return m_it;
 
5431
        }
 
5432
 
 
5433
        /// return value to compare
 
5434
        operator difference_type () const
 
5435
        {
 
5436
            return m_it;
 
5437
        }
 
5438
 
 
5439
      private:
 
5440
        static constexpr difference_type begin_value = 0;
 
5441
        static constexpr difference_type end_value = begin_value + 1;
 
5442
 
 
5443
        /// iterator as signed integer type
 
5444
        difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
 
5445
    };
 
5446
 
 
5447
    /*!
 
5448
    @brief an iterator value
 
5449
 
 
5450
    @note This structure could easily be a union, but MSVC currently does not
 
5451
    allow unions members with complex constructors, see
 
5452
    https://github.com/nlohmann/json/pull/105.
 
5453
    */
 
5454
    struct internal_iterator
 
5455
    {
 
5456
        /// iterator for JSON objects
 
5457
        typename object_t::iterator object_iterator;
 
5458
        /// iterator for JSON arrays
 
5459
        typename array_t::iterator array_iterator;
 
5460
        /// generic iterator for all other types
 
5461
        primitive_iterator_t primitive_iterator;
 
5462
 
 
5463
        /// create an uninitialized internal_iterator
 
5464
        internal_iterator()
 
5465
            : object_iterator(), array_iterator(), primitive_iterator()
 
5466
        {}
 
5467
    };
 
5468
 
 
5469
    /// proxy class for the iterator_wrapper functions
 
5470
    template<typename IteratorType>
 
5471
    class iteration_proxy
 
5472
    {
 
5473
      private:
 
5474
        /// helper class for iteration
 
5475
        class iteration_proxy_internal
 
5476
        {
 
5477
          private:
 
5478
            /// the iterator
 
5479
            IteratorType anchor;
 
5480
            /// an index for arrays (used to create key names)
 
5481
            size_t array_index = 0;
 
5482
 
 
5483
          public:
 
5484
            iteration_proxy_internal(IteratorType it)
 
5485
                : anchor(it)
 
5486
            {}
 
5487
 
 
5488
            /// dereference operator (needed for range-based for)
 
5489
            iteration_proxy_internal& operator*()
 
5490
            {
 
5491
                return *this;
 
5492
            }
 
5493
 
 
5494
            /// increment operator (needed for range-based for)
 
5495
            iteration_proxy_internal& operator++()
 
5496
            {
 
5497
                ++anchor;
 
5498
                ++array_index;
 
5499
 
 
5500
                return *this;
 
5501
            }
 
5502
 
 
5503
            /// inequality operator (needed for range-based for)
 
5504
            bool operator!= (const iteration_proxy_internal& o) const
 
5505
            {
 
5506
                return anchor != o.anchor;
 
5507
            }
 
5508
 
 
5509
            /// return key of the iterator
 
5510
            typename basic_json::string_t key() const
 
5511
            {
 
5512
                switch (anchor.m_object->type())
 
5513
                {
 
5514
                    // use integer array index as key
 
5515
                    case value_t::array:
 
5516
                    {
 
5517
                        return std::to_string(array_index);
 
5518
                    }
 
5519
 
 
5520
                    // use key from the object
 
5521
                    case value_t::object:
 
5522
                    {
 
5523
                        return anchor.key();
 
5524
                    }
 
5525
 
 
5526
                    // use an empty key for all primitive types
 
5527
                    default:
 
5528
                    {
 
5529
                        return "";
 
5530
                    }
 
5531
                }
 
5532
            }
 
5533
 
 
5534
            /// return value of the iterator
 
5535
            typename IteratorType::reference value() const
 
5536
            {
 
5537
                return anchor.value();
 
5538
            }
 
5539
        };
 
5540
 
 
5541
        /// the container to iterate
 
5542
        typename IteratorType::reference container;
 
5543
 
 
5544
      public:
 
5545
        /// construct iteration proxy from a container
 
5546
        iteration_proxy(typename IteratorType::reference cont)
 
5547
            : container(cont)
 
5548
        {}
 
5549
 
 
5550
        /// return iterator begin (needed for range-based for)
 
5551
        iteration_proxy_internal begin()
 
5552
        {
 
5553
            return iteration_proxy_internal(container.begin());
 
5554
        }
 
5555
 
 
5556
        /// return iterator end (needed for range-based for)
 
5557
        iteration_proxy_internal end()
 
5558
        {
 
5559
            return iteration_proxy_internal(container.end());
 
5560
        }
 
5561
    };
 
5562
 
 
5563
  public:
 
5564
    /*!
 
5565
    @brief a const random access iterator for the @ref basic_json class
 
5566
 
 
5567
    This class implements a const iterator for the @ref basic_json class. From
 
5568
    this class, the @ref iterator class is derived.
 
5569
 
 
5570
    @requirement The class satisfies the following concept requirements:
 
5571
    - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
 
5572
      The iterator that can be moved to point (forward and backward) to any
 
5573
      element in constant time.
 
5574
 
 
5575
    @since version 1.0.0
 
5576
    */
 
5577
    class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
 
5578
    {
 
5579
        /// allow basic_json to access private members
 
5580
        friend class basic_json;
 
5581
 
 
5582
      public:
 
5583
        /// the type of the values when the iterator is dereferenced
 
5584
        using value_type = typename basic_json::value_type;
 
5585
        /// a type to represent differences between iterators
 
5586
        using difference_type = typename basic_json::difference_type;
 
5587
        /// defines a pointer to the type iterated over (value_type)
 
5588
        using pointer = typename basic_json::const_pointer;
 
5589
        /// defines a reference to the type iterated over (value_type)
 
5590
        using reference = typename basic_json::const_reference;
 
5591
        /// the category of the iterator
 
5592
        using iterator_category = std::bidirectional_iterator_tag;
 
5593
 
 
5594
        /// default constructor
 
5595
        const_iterator() = default;
 
5596
 
 
5597
        /// constructor for a given JSON instance
 
5598
        const_iterator(pointer object) : m_object(object)
 
5599
        {
 
5600
            switch (m_object->m_type)
 
5601
            {
 
5602
                case basic_json::value_t::object:
 
5603
                {
 
5604
                    m_it.object_iterator = typename object_t::iterator();
 
5605
                    break;
 
5606
                }
 
5607
 
 
5608
                case basic_json::value_t::array:
 
5609
                {
 
5610
                    m_it.array_iterator = typename array_t::iterator();
 
5611
                    break;
 
5612
                }
 
5613
 
 
5614
                default:
 
5615
                {
 
5616
                    m_it.primitive_iterator = primitive_iterator_t();
 
5617
                    break;
 
5618
                }
 
5619
            }
 
5620
        }
 
5621
 
 
5622
        /// copy constructor given a nonconst iterator
 
5623
        const_iterator(const iterator& other) : m_object(other.m_object)
 
5624
        {
 
5625
            switch (m_object->m_type)
 
5626
            {
 
5627
                case basic_json::value_t::object:
 
5628
                {
 
5629
                    m_it.object_iterator = other.m_it.object_iterator;
 
5630
                    break;
 
5631
                }
 
5632
 
 
5633
                case basic_json::value_t::array:
 
5634
                {
 
5635
                    m_it.array_iterator = other.m_it.array_iterator;
 
5636
                    break;
 
5637
                }
 
5638
 
 
5639
                default:
 
5640
                {
 
5641
                    m_it.primitive_iterator = other.m_it.primitive_iterator;
 
5642
                    break;
 
5643
                }
 
5644
            }
 
5645
        }
 
5646
 
 
5647
        /// copy constructor
 
5648
        const_iterator(const const_iterator& other) noexcept
 
5649
            : m_object(other.m_object), m_it(other.m_it)
 
5650
        {}
 
5651
 
 
5652
        /// copy assignment
 
5653
        const_iterator& operator=(const_iterator other) noexcept(
 
5654
            std::is_nothrow_move_constructible<pointer>::value and
 
5655
            std::is_nothrow_move_assignable<pointer>::value and
 
5656
            std::is_nothrow_move_constructible<internal_iterator>::value and
 
5657
            std::is_nothrow_move_assignable<internal_iterator>::value
 
5658
        )
 
5659
        {
 
5660
            std::swap(m_object, other.m_object);
 
5661
            std::swap(m_it, other.m_it);
 
5662
            return *this;
 
5663
        }
 
5664
 
 
5665
      private:
 
5666
        /// set the iterator to the first value
 
5667
        void set_begin()
 
5668
        {
 
5669
            switch (m_object->m_type)
 
5670
            {
 
5671
                case basic_json::value_t::object:
 
5672
                {
 
5673
                    m_it.object_iterator = m_object->m_value.object->begin();
 
5674
                    break;
 
5675
                }
 
5676
 
 
5677
                case basic_json::value_t::array:
 
5678
                {
 
5679
                    m_it.array_iterator = m_object->m_value.array->begin();
 
5680
                    break;
 
5681
                }
 
5682
 
 
5683
                case basic_json::value_t::null:
 
5684
                {
 
5685
                    // set to end so begin()==end() is true: null is empty
 
5686
                    m_it.primitive_iterator.set_end();
 
5687
                    break;
 
5688
                }
 
5689
 
 
5690
                default:
 
5691
                {
 
5692
                    m_it.primitive_iterator.set_begin();
 
5693
                    break;
 
5694
                }
 
5695
            }
 
5696
        }
 
5697
 
 
5698
        /// set the iterator past the last value
 
5699
        void set_end()
 
5700
        {
 
5701
            switch (m_object->m_type)
 
5702
            {
 
5703
                case basic_json::value_t::object:
 
5704
                {
 
5705
                    m_it.object_iterator = m_object->m_value.object->end();
 
5706
                    break;
 
5707
                }
 
5708
 
 
5709
                case basic_json::value_t::array:
 
5710
                {
 
5711
                    m_it.array_iterator = m_object->m_value.array->end();
 
5712
                    break;
 
5713
                }
 
5714
 
 
5715
                default:
 
5716
                {
 
5717
                    m_it.primitive_iterator.set_end();
 
5718
                    break;
 
5719
                }
 
5720
            }
 
5721
        }
 
5722
 
 
5723
      public:
 
5724
        /// return a reference to the value pointed to by the iterator
 
5725
        reference operator*() const
 
5726
        {
 
5727
            switch (m_object->m_type)
 
5728
            {
 
5729
                case basic_json::value_t::object:
 
5730
                {
 
5731
                    return m_it.object_iterator->second;
 
5732
                }
 
5733
 
 
5734
                case basic_json::value_t::array:
 
5735
                {
 
5736
                    return *m_it.array_iterator;
 
5737
                }
 
5738
 
 
5739
                case basic_json::value_t::null:
 
5740
                {
 
5741
                    throw std::out_of_range("cannot get value");
 
5742
                }
 
5743
 
 
5744
                default:
 
5745
                {
 
5746
                    if (m_it.primitive_iterator.is_begin())
 
5747
                    {
 
5748
                        return *m_object;
 
5749
                    }
 
5750
                    else
 
5751
                    {
 
5752
                        throw std::out_of_range("cannot get value");
 
5753
                    }
 
5754
                }
 
5755
            }
 
5756
        }
 
5757
 
 
5758
        /// dereference the iterator
 
5759
        pointer operator->() const
 
5760
        {
 
5761
            switch (m_object->m_type)
 
5762
            {
 
5763
                case basic_json::value_t::object:
 
5764
                {
 
5765
                    return &(m_it.object_iterator->second);
 
5766
                }
 
5767
 
 
5768
                case basic_json::value_t::array:
 
5769
                {
 
5770
                    return &*m_it.array_iterator;
 
5771
                }
 
5772
 
 
5773
                default:
 
5774
                {
 
5775
                    if (m_it.primitive_iterator.is_begin())
 
5776
                    {
 
5777
                        return m_object;
 
5778
                    }
 
5779
                    else
 
5780
                    {
 
5781
                        throw std::out_of_range("cannot get value");
 
5782
                    }
 
5783
                }
 
5784
            }
 
5785
        }
 
5786
 
 
5787
        /// post-increment (it++)
 
5788
        const_iterator operator++(int)
 
5789
        {
 
5790
            auto result = *this;
 
5791
            ++(*this);
 
5792
            return result;
 
5793
        }
 
5794
 
 
5795
        /// pre-increment (++it)
 
5796
        const_iterator& operator++()
 
5797
        {
 
5798
            switch (m_object->m_type)
 
5799
            {
 
5800
                case basic_json::value_t::object:
 
5801
                {
 
5802
                    ++m_it.object_iterator;
 
5803
                    break;
 
5804
                }
 
5805
 
 
5806
                case basic_json::value_t::array:
 
5807
                {
 
5808
                    ++m_it.array_iterator;
 
5809
                    break;
 
5810
                }
 
5811
 
 
5812
                default:
 
5813
                {
 
5814
                    ++m_it.primitive_iterator;
 
5815
                    break;
 
5816
                }
 
5817
            }
 
5818
 
 
5819
            return *this;
 
5820
        }
 
5821
 
 
5822
        /// post-decrement (it--)
 
5823
        const_iterator operator--(int)
 
5824
        {
 
5825
            auto result = *this;
 
5826
            --(*this);
 
5827
            return result;
 
5828
        }
 
5829
 
 
5830
        /// pre-decrement (--it)
 
5831
        const_iterator& operator--()
 
5832
        {
 
5833
            switch (m_object->m_type)
 
5834
            {
 
5835
                case basic_json::value_t::object:
 
5836
                {
 
5837
                    --m_it.object_iterator;
 
5838
                    break;
 
5839
                }
 
5840
 
 
5841
                case basic_json::value_t::array:
 
5842
                {
 
5843
                    --m_it.array_iterator;
 
5844
                    break;
 
5845
                }
 
5846
 
 
5847
                default:
 
5848
                {
 
5849
                    --m_it.primitive_iterator;
 
5850
                    break;
 
5851
                }
 
5852
            }
 
5853
 
 
5854
            return *this;
 
5855
        }
 
5856
 
 
5857
        /// comparison: equal
 
5858
        bool operator==(const const_iterator& other) const
 
5859
        {
 
5860
            // if objects are not the same, the comparison is undefined
 
5861
            if (m_object != other.m_object)
 
5862
            {
 
5863
                throw std::domain_error("cannot compare iterators of different containers");
 
5864
            }
 
5865
 
 
5866
            switch (m_object->m_type)
 
5867
            {
 
5868
                case basic_json::value_t::object:
 
5869
                {
 
5870
                    return (m_it.object_iterator == other.m_it.object_iterator);
 
5871
                }
 
5872
 
 
5873
                case basic_json::value_t::array:
 
5874
                {
 
5875
                    return (m_it.array_iterator == other.m_it.array_iterator);
 
5876
                }
 
5877
 
 
5878
                default:
 
5879
                {
 
5880
                    return (m_it.primitive_iterator == other.m_it.primitive_iterator);
 
5881
                }
 
5882
            }
 
5883
        }
 
5884
 
 
5885
        /// comparison: not equal
 
5886
        bool operator!=(const const_iterator& other) const
 
5887
        {
 
5888
            return not operator==(other);
 
5889
        }
 
5890
 
 
5891
        /// comparison: smaller
 
5892
        bool operator<(const const_iterator& other) const
 
5893
        {
 
5894
            // if objects are not the same, the comparison is undefined
 
5895
            if (m_object != other.m_object)
 
5896
            {
 
5897
                throw std::domain_error("cannot compare iterators of different containers");
 
5898
            }
 
5899
 
 
5900
            switch (m_object->m_type)
 
5901
            {
 
5902
                case basic_json::value_t::object:
 
5903
                {
 
5904
                    throw std::domain_error("cannot compare order of object iterators");
 
5905
                }
 
5906
 
 
5907
                case basic_json::value_t::array:
 
5908
                {
 
5909
                    return (m_it.array_iterator < other.m_it.array_iterator);
 
5910
                }
 
5911
 
 
5912
                default:
 
5913
                {
 
5914
                    return (m_it.primitive_iterator < other.m_it.primitive_iterator);
 
5915
                }
 
5916
            }
 
5917
        }
 
5918
 
 
5919
        /// comparison: less than or equal
 
5920
        bool operator<=(const const_iterator& other) const
 
5921
        {
 
5922
            return not other.operator < (*this);
 
5923
        }
 
5924
 
 
5925
        /// comparison: greater than
 
5926
        bool operator>(const const_iterator& other) const
 
5927
        {
 
5928
            return not operator<=(other);
 
5929
        }
 
5930
 
 
5931
        /// comparison: greater than or equal
 
5932
        bool operator>=(const const_iterator& other) const
 
5933
        {
 
5934
            return not operator<(other);
 
5935
        }
 
5936
 
 
5937
        /// add to iterator
 
5938
        const_iterator& operator+=(difference_type i)
 
5939
        {
 
5940
            switch (m_object->m_type)
 
5941
            {
 
5942
                case basic_json::value_t::object:
 
5943
                {
 
5944
                    throw std::domain_error("cannot use offsets with object iterators");
 
5945
                }
 
5946
 
 
5947
                case basic_json::value_t::array:
 
5948
                {
 
5949
                    m_it.array_iterator += i;
 
5950
                    break;
 
5951
                }
 
5952
 
 
5953
                default:
 
5954
                {
 
5955
                    m_it.primitive_iterator += i;
 
5956
                    break;
 
5957
                }
 
5958
            }
 
5959
 
 
5960
            return *this;
 
5961
        }
 
5962
 
 
5963
        /// subtract from iterator
 
5964
        const_iterator& operator-=(difference_type i)
 
5965
        {
 
5966
            return operator+=(-i);
 
5967
        }
 
5968
 
 
5969
        /// add to iterator
 
5970
        const_iterator operator+(difference_type i)
 
5971
        {
 
5972
            auto result = *this;
 
5973
            result += i;
 
5974
            return result;
 
5975
        }
 
5976
 
 
5977
        /// subtract from iterator
 
5978
        const_iterator operator-(difference_type i)
 
5979
        {
 
5980
            auto result = *this;
 
5981
            result -= i;
 
5982
            return result;
 
5983
        }
 
5984
 
 
5985
        /// return difference
 
5986
        difference_type operator-(const const_iterator& other) const
 
5987
        {
 
5988
            switch (m_object->m_type)
 
5989
            {
 
5990
                case basic_json::value_t::object:
 
5991
                {
 
5992
                    throw std::domain_error("cannot use offsets with object iterators");
 
5993
                }
 
5994
 
 
5995
                case basic_json::value_t::array:
 
5996
                {
 
5997
                    return m_it.array_iterator - other.m_it.array_iterator;
 
5998
                }
 
5999
 
 
6000
                default:
 
6001
                {
 
6002
                    return m_it.primitive_iterator - other.m_it.primitive_iterator;
 
6003
                }
 
6004
            }
 
6005
        }
 
6006
 
 
6007
        /// access to successor
 
6008
        reference operator[](difference_type n) const
 
6009
        {
 
6010
            switch (m_object->m_type)
 
6011
            {
 
6012
                case basic_json::value_t::object:
 
6013
                {
 
6014
                    throw std::domain_error("cannot use operator[] for object iterators");
 
6015
                }
 
6016
 
 
6017
                case basic_json::value_t::array:
 
6018
                {
 
6019
                    return *(m_it.array_iterator + n);
 
6020
                }
 
6021
 
 
6022
                case basic_json::value_t::null:
 
6023
                {
 
6024
                    throw std::out_of_range("cannot get value");
 
6025
                }
 
6026
 
 
6027
                default:
 
6028
                {
 
6029
                    if (m_it.primitive_iterator == -n)
 
6030
                    {
 
6031
                        return *m_object;
 
6032
                    }
 
6033
                    else
 
6034
                    {
 
6035
                        throw std::out_of_range("cannot get value");
 
6036
                    }
 
6037
                }
 
6038
            }
 
6039
        }
 
6040
 
 
6041
        /// return the key of an object iterator
 
6042
        typename object_t::key_type key() const
 
6043
        {
 
6044
            if (m_object->is_object())
 
6045
            {
 
6046
                return m_it.object_iterator->first;
 
6047
            }
 
6048
            else
 
6049
            {
 
6050
                throw std::domain_error("cannot use key() for non-object iterators");
 
6051
            }
 
6052
        }
 
6053
 
 
6054
        /// return the value of an iterator
 
6055
        reference value() const
 
6056
        {
 
6057
            return operator*();
 
6058
        }
 
6059
 
 
6060
      private:
 
6061
        /// associated JSON instance
 
6062
        pointer m_object = nullptr;
 
6063
        /// the actual iterator of the associated instance
 
6064
        internal_iterator m_it = internal_iterator();
 
6065
    };
 
6066
 
 
6067
    /*!
 
6068
    @brief a mutable random access iterator for the @ref basic_json class
 
6069
 
 
6070
    @requirement The class satisfies the following concept requirements:
 
6071
    - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
 
6072
      The iterator that can be moved to point (forward and backward) to any
 
6073
      element in constant time.
 
6074
    - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
 
6075
      It is possible to write to the pointed-to element.
 
6076
 
 
6077
    @since version 1.0.0
 
6078
    */
 
6079
    class iterator : public const_iterator
 
6080
    {
 
6081
      public:
 
6082
        using base_iterator = const_iterator;
 
6083
        using pointer = typename basic_json::pointer;
 
6084
        using reference = typename basic_json::reference;
 
6085
 
 
6086
        /// default constructor
 
6087
        iterator() = default;
 
6088
 
 
6089
        /// constructor for a given JSON instance
 
6090
        iterator(pointer object) noexcept
 
6091
            : base_iterator(object)
 
6092
        {}
 
6093
 
 
6094
        /// copy constructor
 
6095
        iterator(const iterator& other) noexcept
 
6096
            : base_iterator(other)
 
6097
        {}
 
6098
 
 
6099
        /// copy assignment
 
6100
        iterator& operator=(iterator other) noexcept(
 
6101
            std::is_nothrow_move_constructible<pointer>::value and
 
6102
            std::is_nothrow_move_assignable<pointer>::value and
 
6103
            std::is_nothrow_move_constructible<internal_iterator>::value and
 
6104
            std::is_nothrow_move_assignable<internal_iterator>::value
 
6105
        )
 
6106
        {
 
6107
            base_iterator::operator=(other);
 
6108
            return *this;
 
6109
        }
 
6110
 
 
6111
        /// return a reference to the value pointed to by the iterator
 
6112
        reference operator*()
 
6113
        {
 
6114
            return const_cast<reference>(base_iterator::operator*());
 
6115
        }
 
6116
 
 
6117
        /// dereference the iterator
 
6118
        pointer operator->()
 
6119
        {
 
6120
            return const_cast<pointer>(base_iterator::operator->());
 
6121
        }
 
6122
 
 
6123
        /// post-increment (it++)
 
6124
        iterator operator++(int)
 
6125
        {
 
6126
            iterator result = *this;
 
6127
            base_iterator::operator++();
 
6128
            return result;
 
6129
        }
 
6130
 
 
6131
        /// pre-increment (++it)
 
6132
        iterator& operator++()
 
6133
        {
 
6134
            base_iterator::operator++();
 
6135
            return *this;
 
6136
        }
 
6137
 
 
6138
        /// post-decrement (it--)
 
6139
        iterator operator--(int)
 
6140
        {
 
6141
            iterator result = *this;
 
6142
            base_iterator::operator--();
 
6143
            return result;
 
6144
        }
 
6145
 
 
6146
        /// pre-decrement (--it)
 
6147
        iterator& operator--()
 
6148
        {
 
6149
            base_iterator::operator--();
 
6150
            return *this;
 
6151
        }
 
6152
 
 
6153
        /// add to iterator
 
6154
        iterator& operator+=(difference_type i)
 
6155
        {
 
6156
            base_iterator::operator+=(i);
 
6157
            return *this;
 
6158
        }
 
6159
 
 
6160
        /// subtract from iterator
 
6161
        iterator& operator-=(difference_type i)
 
6162
        {
 
6163
            base_iterator::operator-=(i);
 
6164
            return *this;
 
6165
        }
 
6166
 
 
6167
        /// add to iterator
 
6168
        iterator operator+(difference_type i)
 
6169
        {
 
6170
            auto result = *this;
 
6171
            result += i;
 
6172
            return result;
 
6173
        }
 
6174
 
 
6175
        /// subtract from iterator
 
6176
        iterator operator-(difference_type i)
 
6177
        {
 
6178
            auto result = *this;
 
6179
            result -= i;
 
6180
            return result;
 
6181
        }
 
6182
 
 
6183
        difference_type operator-(const iterator& other) const
 
6184
        {
 
6185
            return base_iterator::operator-(other);
 
6186
        }
 
6187
 
 
6188
        /// access to successor
 
6189
        reference operator[](difference_type n) const
 
6190
        {
 
6191
            return const_cast<reference>(base_iterator::operator[](n));
 
6192
        }
 
6193
 
 
6194
        /// return the value of an iterator
 
6195
        reference value() const
 
6196
        {
 
6197
            return const_cast<reference>(base_iterator::value());
 
6198
        }
 
6199
    };
 
6200
 
 
6201
    /*!
 
6202
    @brief a template for a reverse iterator class
 
6203
 
 
6204
    @tparam Base the base iterator type to reverse. Valid types are @ref
 
6205
    iterator (to create @ref reverse_iterator) and @ref const_iterator (to
 
6206
    create @ref const_reverse_iterator).
 
6207
 
 
6208
    @requirement The class satisfies the following concept requirements:
 
6209
    - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
 
6210
      The iterator that can be moved to point (forward and backward) to any
 
6211
      element in constant time.
 
6212
    - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
 
6213
      It is possible to write to the pointed-to element (only if @a Base is
 
6214
      @ref iterator).
 
6215
 
 
6216
    @since version 1.0.0
 
6217
    */
 
6218
    template<typename Base>
 
6219
    class json_reverse_iterator : public std::reverse_iterator<Base>
 
6220
    {
 
6221
      public:
 
6222
        /// shortcut to the reverse iterator adaptor
 
6223
        using base_iterator = std::reverse_iterator<Base>;
 
6224
        /// the reference type for the pointed-to element
 
6225
        using reference = typename Base::reference;
 
6226
 
 
6227
        /// create reverse iterator from iterator
 
6228
        json_reverse_iterator(const typename base_iterator::iterator_type& it)
 
6229
            : base_iterator(it)
 
6230
        {}
 
6231
 
 
6232
        /// create reverse iterator from base class
 
6233
        json_reverse_iterator(const base_iterator& it)
 
6234
            : base_iterator(it)
 
6235
        {}
 
6236
 
 
6237
        /// post-increment (it++)
 
6238
        json_reverse_iterator operator++(int)
 
6239
        {
 
6240
            return base_iterator::operator++(1);
 
6241
        }
 
6242
 
 
6243
        /// pre-increment (++it)
 
6244
        json_reverse_iterator& operator++()
 
6245
        {
 
6246
            base_iterator::operator++();
 
6247
            return *this;
 
6248
        }
 
6249
 
 
6250
        /// post-decrement (it--)
 
6251
        json_reverse_iterator operator--(int)
 
6252
        {
 
6253
            return base_iterator::operator--(1);
 
6254
        }
 
6255
 
 
6256
        /// pre-decrement (--it)
 
6257
        json_reverse_iterator& operator--()
 
6258
        {
 
6259
            base_iterator::operator--();
 
6260
            return *this;
 
6261
        }
 
6262
 
 
6263
        /// add to iterator
 
6264
        json_reverse_iterator& operator+=(difference_type i)
 
6265
        {
 
6266
            base_iterator::operator+=(i);
 
6267
            return *this;
 
6268
        }
 
6269
 
 
6270
        /// add to iterator
 
6271
        json_reverse_iterator operator+(difference_type i) const
 
6272
        {
 
6273
            auto result = *this;
 
6274
            result += i;
 
6275
            return result;
 
6276
        }
 
6277
 
 
6278
        /// subtract from iterator
 
6279
        json_reverse_iterator operator-(difference_type i) const
 
6280
        {
 
6281
            auto result = *this;
 
6282
            result -= i;
 
6283
            return result;
 
6284
        }
 
6285
 
 
6286
        /// return difference
 
6287
        difference_type operator-(const json_reverse_iterator& other) const
 
6288
        {
 
6289
            return this->base() - other.base();
 
6290
        }
 
6291
 
 
6292
        /// access to successor
 
6293
        reference operator[](difference_type n) const
 
6294
        {
 
6295
            return *(this->operator+(n));
 
6296
        }
 
6297
 
 
6298
        /// return the key of an object iterator
 
6299
        typename object_t::key_type key() const
 
6300
        {
 
6301
            auto it = --this->base();
 
6302
            return it.key();
 
6303
        }
 
6304
 
 
6305
        /// return the value of an iterator
 
6306
        reference value() const
 
6307
        {
 
6308
            auto it = --this->base();
 
6309
            return it.operator * ();
 
6310
        }
 
6311
    };
 
6312
 
 
6313
 
 
6314
  private:
 
6315
    //////////////////////
 
6316
    // lexer and parser //
 
6317
    //////////////////////
 
6318
 
 
6319
    /*!
 
6320
    @brief lexical analysis
 
6321
 
 
6322
    This class organizes the lexical analysis during JSON deserialization. The
 
6323
    core of it is a scanner generated by re2c <http://re2c.org> that processes
 
6324
    a buffer and recognizes tokens according to RFC 7159.
 
6325
    */
 
6326
    class lexer
 
6327
    {
 
6328
      public:
 
6329
        /// token types for the parser
 
6330
        enum class token_type
 
6331
        {
 
6332
            uninitialized,    ///< indicating the scanner is uninitialized
 
6333
            literal_true,     ///< the "true" literal
 
6334
            literal_false,    ///< the "false" literal
 
6335
            literal_null,     ///< the "null" literal
 
6336
            value_string,     ///< a string -- use get_string() for actual value
 
6337
            value_number,     ///< a number -- use get_number() for actual value
 
6338
            begin_array,      ///< the character for array begin "["
 
6339
            begin_object,     ///< the character for object begin "{"
 
6340
            end_array,        ///< the character for array end "]"
 
6341
            end_object,       ///< the character for object end "}"
 
6342
            name_separator,   ///< the name separator ":"
 
6343
            value_separator,  ///< the value separator ","
 
6344
            parse_error,      ///< indicating a parse error
 
6345
            end_of_input      ///< indicating the end of the input buffer
 
6346
        };
 
6347
 
 
6348
        /// the char type to use in the lexer
 
6349
        using lexer_char_t = unsigned char;
 
6350
 
 
6351
        /// constructor with a given buffer
 
6352
        explicit lexer(const string_t& s) noexcept
 
6353
            : m_stream(nullptr), m_buffer(s)
 
6354
        {
 
6355
            m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
 
6356
            m_start = m_cursor = m_content;
 
6357
            m_limit = m_content + s.size();
 
6358
        }
 
6359
 
 
6360
        /// constructor with a given stream
 
6361
        explicit lexer(std::istream* s) noexcept
 
6362
            : m_stream(s), m_buffer()
 
6363
        {
 
6364
            getline(*m_stream, m_buffer);
 
6365
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 
6366
            m_start = m_cursor = m_content;
 
6367
            m_limit = m_content + m_buffer.size();
 
6368
        }
 
6369
 
 
6370
        /// default constructor
 
6371
        lexer() = default;
 
6372
 
 
6373
        // switch off unwanted functions
 
6374
        lexer(const lexer&) = delete;
 
6375
        lexer operator=(const lexer&) = delete;
 
6376
 
 
6377
        /*!
 
6378
        @brief create a string from a Unicode code point
 
6379
 
 
6380
        @param[in] codepoint1  the code point (can be high surrogate)
 
6381
        @param[in] codepoint2  the code point (can be low surrogate or 0)
 
6382
 
 
6383
        @return string representation of the code point
 
6384
 
 
6385
        @throw std::out_of_range if code point is >0x10ffff; example: `"code
 
6386
        points above 0x10FFFF are invalid"`
 
6387
        @throw std::invalid_argument if the low surrogate is invalid; example:
 
6388
        `""missing or wrong low surrogate""`
 
6389
 
 
6390
        @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
 
6391
        */
 
6392
        static string_t to_unicode(const std::size_t codepoint1,
 
6393
                                   const std::size_t codepoint2 = 0)
 
6394
        {
 
6395
            string_t result;
 
6396
 
 
6397
            // calculate the codepoint from the given code points
 
6398
            std::size_t codepoint = codepoint1;
 
6399
 
 
6400
            // check if codepoint1 is a high surrogate
 
6401
            if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
 
6402
            {
 
6403
                // check if codepoint2 is a low surrogate
 
6404
                if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
 
6405
                {
 
6406
                    codepoint =
 
6407
                        // high surrogate occupies the most significant 22 bits
 
6408
                        (codepoint1 << 10)
 
6409
                        // low surrogate occupies the least significant 15 bits
 
6410
                        + codepoint2
 
6411
                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
 
6412
                        // in the result so we have to substract with:
 
6413
                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
 
6414
                        - 0x35FDC00;
 
6415
                }
 
6416
                else
 
6417
                {
 
6418
                    throw std::invalid_argument("missing or wrong low surrogate");
 
6419
                }
 
6420
            }
 
6421
 
 
6422
            if (codepoint < 0x80)
 
6423
            {
 
6424
                // 1-byte characters: 0xxxxxxx (ASCII)
 
6425
                result.append(1, static_cast<typename string_t::value_type>(codepoint));
 
6426
            }
 
6427
            else if (codepoint <= 0x7ff)
 
6428
            {
 
6429
                // 2-byte characters: 110xxxxx 10xxxxxx
 
6430
                result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
 
6431
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
 
6432
            }
 
6433
            else if (codepoint <= 0xffff)
 
6434
            {
 
6435
                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
 
6436
                result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
 
6437
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
 
6438
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
 
6439
            }
 
6440
            else if (codepoint <= 0x10ffff)
 
6441
            {
 
6442
                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 
6443
                result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
 
6444
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
 
6445
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
 
6446
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
 
6447
            }
 
6448
            else
 
6449
            {
 
6450
                throw std::out_of_range("code points above 0x10FFFF are invalid");
 
6451
            }
 
6452
 
 
6453
            return result;
 
6454
        }
 
6455
 
 
6456
        /// return name of values of type token_type (only used for errors)
 
6457
        static std::string token_type_name(token_type t)
 
6458
        {
 
6459
            switch (t)
 
6460
            {
 
6461
                case token_type::uninitialized:
 
6462
                    return "<uninitialized>";
 
6463
                case token_type::literal_true:
 
6464
                    return "true literal";
 
6465
                case token_type::literal_false:
 
6466
                    return "false literal";
 
6467
                case token_type::literal_null:
 
6468
                    return "null literal";
 
6469
                case token_type::value_string:
 
6470
                    return "string literal";
 
6471
                case token_type::value_number:
 
6472
                    return "number literal";
 
6473
                case token_type::begin_array:
 
6474
                    return "'['";
 
6475
                case token_type::begin_object:
 
6476
                    return "'{'";
 
6477
                case token_type::end_array:
 
6478
                    return "']'";
 
6479
                case token_type::end_object:
 
6480
                    return "'}'";
 
6481
                case token_type::name_separator:
 
6482
                    return "':'";
 
6483
                case token_type::value_separator:
 
6484
                    return "','";
 
6485
                case token_type::parse_error:
 
6486
                    return "<parse error>";
 
6487
                case token_type::end_of_input:
 
6488
                    return "end of input";
 
6489
                default:
 
6490
                {
 
6491
                    // catch non-enum values
 
6492
                    return "unknown token"; // LCOV_EXCL_LINE
 
6493
                }
 
6494
            }
 
6495
        }
 
6496
 
 
6497
        /*!
 
6498
        This function implements a scanner for JSON. It is specified using
 
6499
        regular expressions that try to follow RFC 7159 as close as possible.
 
6500
        These regular expressions are then translated into a deterministic
 
6501
        finite automaton (DFA) by the tool re2c <http://re2c.org>. As a result,
 
6502
        the translated code for this function consists of a large block of code
 
6503
        with goto jumps.
 
6504
 
 
6505
        @return the class of the next token read from the buffer
 
6506
        */
 
6507
        token_type scan() noexcept
 
6508
        {
 
6509
            // pointer for backtracking information
 
6510
            m_marker = nullptr;
 
6511
 
 
6512
            // remember the begin of the token
 
6513
            m_start = m_cursor;
 
6514
 
 
6515
 
 
6516
            {
 
6517
                lexer_char_t yych;
 
6518
                unsigned int yyaccept = 0;
 
6519
                static const unsigned char yybm[] =
 
6520
                {
 
6521
                    0,   0,   0,   0,   0,   0,   0,   0,
 
6522
                    0,  32,  32,   0,   0,  32,   0,   0,
 
6523
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6524
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6525
                    96,  64,   0,  64,  64,  64,  64,  64,
 
6526
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6527
                    192, 192, 192, 192, 192, 192, 192, 192,
 
6528
                    192, 192,  64,  64,  64,  64,  64,  64,
 
6529
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6530
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6531
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6532
                    64,  64,  64,  64,   0,  64,  64,  64,
 
6533
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6534
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6535
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6536
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6537
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6538
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6539
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6540
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6541
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6542
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6543
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6544
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6545
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6546
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6547
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6548
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6549
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6550
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6551
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6552
                    64,  64,  64,  64,  64,  64,  64,  64,
 
6553
                };
 
6554
                if ((m_limit - m_cursor) < 5)
 
6555
                {
 
6556
                    yyfill();    // LCOV_EXCL_LINE;
 
6557
                }
 
6558
                yych = *m_cursor;
 
6559
                if (yych <= ':')
 
6560
                {
 
6561
                    if (yych <= ' ')
 
6562
                    {
 
6563
                        if (yych <= '\n')
 
6564
                        {
 
6565
                            if (yych <= 0x00)
 
6566
                            {
 
6567
                                goto basic_json_parser_28;
 
6568
                            }
 
6569
                            if (yych <= 0x08)
 
6570
                            {
 
6571
                                goto basic_json_parser_30;
 
6572
                            }
 
6573
                            if (yych >= '\n')
 
6574
                            {
 
6575
                                goto basic_json_parser_4;
 
6576
                            }
 
6577
                        }
 
6578
                        else
 
6579
                        {
 
6580
                            if (yych == '\r')
 
6581
                            {
 
6582
                                goto basic_json_parser_2;
 
6583
                            }
 
6584
                            if (yych <= 0x1F)
 
6585
                            {
 
6586
                                goto basic_json_parser_30;
 
6587
                            }
 
6588
                        }
 
6589
                    }
 
6590
                    else
 
6591
                    {
 
6592
                        if (yych <= ',')
 
6593
                        {
 
6594
                            if (yych == '"')
 
6595
                            {
 
6596
                                goto basic_json_parser_27;
 
6597
                            }
 
6598
                            if (yych <= '+')
 
6599
                            {
 
6600
                                goto basic_json_parser_30;
 
6601
                            }
 
6602
                            goto basic_json_parser_16;
 
6603
                        }
 
6604
                        else
 
6605
                        {
 
6606
                            if (yych <= '/')
 
6607
                            {
 
6608
                                if (yych <= '-')
 
6609
                                {
 
6610
                                    goto basic_json_parser_23;
 
6611
                                }
 
6612
                                goto basic_json_parser_30;
 
6613
                            }
 
6614
                            else
 
6615
                            {
 
6616
                                if (yych <= '0')
 
6617
                                {
 
6618
                                    goto basic_json_parser_24;
 
6619
                                }
 
6620
                                if (yych <= '9')
 
6621
                                {
 
6622
                                    goto basic_json_parser_26;
 
6623
                                }
 
6624
                                goto basic_json_parser_18;
 
6625
                            }
 
6626
                        }
 
6627
                    }
 
6628
                }
 
6629
                else
 
6630
                {
 
6631
                    if (yych <= 'n')
 
6632
                    {
 
6633
                        if (yych <= ']')
 
6634
                        {
 
6635
                            if (yych == '[')
 
6636
                            {
 
6637
                                goto basic_json_parser_8;
 
6638
                            }
 
6639
                            if (yych <= '\\')
 
6640
                            {
 
6641
                                goto basic_json_parser_30;
 
6642
                            }
 
6643
                            goto basic_json_parser_10;
 
6644
                        }
 
6645
                        else
 
6646
                        {
 
6647
                            if (yych == 'f')
 
6648
                            {
 
6649
                                goto basic_json_parser_22;
 
6650
                            }
 
6651
                            if (yych <= 'm')
 
6652
                            {
 
6653
                                goto basic_json_parser_30;
 
6654
                            }
 
6655
                            goto basic_json_parser_20;
 
6656
                        }
 
6657
                    }
 
6658
                    else
 
6659
                    {
 
6660
                        if (yych <= '{')
 
6661
                        {
 
6662
                            if (yych == 't')
 
6663
                            {
 
6664
                                goto basic_json_parser_21;
 
6665
                            }
 
6666
                            if (yych <= 'z')
 
6667
                            {
 
6668
                                goto basic_json_parser_30;
 
6669
                            }
 
6670
                            goto basic_json_parser_12;
 
6671
                        }
 
6672
                        else
 
6673
                        {
 
6674
                            if (yych <= '}')
 
6675
                            {
 
6676
                                if (yych <= '|')
 
6677
                                {
 
6678
                                    goto basic_json_parser_30;
 
6679
                                }
 
6680
                                goto basic_json_parser_14;
 
6681
                            }
 
6682
                            else
 
6683
                            {
 
6684
                                if (yych == 0xEF)
 
6685
                                {
 
6686
                                    goto basic_json_parser_6;
 
6687
                                }
 
6688
                                goto basic_json_parser_30;
 
6689
                            }
 
6690
                        }
 
6691
                    }
 
6692
                }
 
6693
basic_json_parser_2:
 
6694
                ++m_cursor;
 
6695
                yych = *m_cursor;
 
6696
                goto basic_json_parser_5;
 
6697
basic_json_parser_3:
 
6698
                {
 
6699
                    return scan();
 
6700
                }
 
6701
basic_json_parser_4:
 
6702
                ++m_cursor;
 
6703
                if (m_limit <= m_cursor)
 
6704
                {
 
6705
                    yyfill();    // LCOV_EXCL_LINE;
 
6706
                }
 
6707
                yych = *m_cursor;
 
6708
basic_json_parser_5:
 
6709
                if (yybm[0 + yych] & 32)
 
6710
                {
 
6711
                    goto basic_json_parser_4;
 
6712
                }
 
6713
                goto basic_json_parser_3;
 
6714
basic_json_parser_6:
 
6715
                yyaccept = 0;
 
6716
                yych = *(m_marker = ++m_cursor);
 
6717
                if (yych == 0xBB)
 
6718
                {
 
6719
                    goto basic_json_parser_64;
 
6720
                }
 
6721
basic_json_parser_7:
 
6722
                {
 
6723
                    return token_type::parse_error;
 
6724
                }
 
6725
basic_json_parser_8:
 
6726
                ++m_cursor;
 
6727
                {
 
6728
                    return token_type::begin_array;
 
6729
                }
 
6730
basic_json_parser_10:
 
6731
                ++m_cursor;
 
6732
                {
 
6733
                    return token_type::end_array;
 
6734
                }
 
6735
basic_json_parser_12:
 
6736
                ++m_cursor;
 
6737
                {
 
6738
                    return token_type::begin_object;
 
6739
                }
 
6740
basic_json_parser_14:
 
6741
                ++m_cursor;
 
6742
                {
 
6743
                    return token_type::end_object;
 
6744
                }
 
6745
basic_json_parser_16:
 
6746
                ++m_cursor;
 
6747
                {
 
6748
                    return token_type::value_separator;
 
6749
                }
 
6750
basic_json_parser_18:
 
6751
                ++m_cursor;
 
6752
                {
 
6753
                    return token_type::name_separator;
 
6754
                }
 
6755
basic_json_parser_20:
 
6756
                yyaccept = 0;
 
6757
                yych = *(m_marker = ++m_cursor);
 
6758
                if (yych == 'u')
 
6759
                {
 
6760
                    goto basic_json_parser_60;
 
6761
                }
 
6762
                goto basic_json_parser_7;
 
6763
basic_json_parser_21:
 
6764
                yyaccept = 0;
 
6765
                yych = *(m_marker = ++m_cursor);
 
6766
                if (yych == 'r')
 
6767
                {
 
6768
                    goto basic_json_parser_56;
 
6769
                }
 
6770
                goto basic_json_parser_7;
 
6771
basic_json_parser_22:
 
6772
                yyaccept = 0;
 
6773
                yych = *(m_marker = ++m_cursor);
 
6774
                if (yych == 'a')
 
6775
                {
 
6776
                    goto basic_json_parser_51;
 
6777
                }
 
6778
                goto basic_json_parser_7;
 
6779
basic_json_parser_23:
 
6780
                yych = *++m_cursor;
 
6781
                if (yych <= '/')
 
6782
                {
 
6783
                    goto basic_json_parser_7;
 
6784
                }
 
6785
                if (yych <= '0')
 
6786
                {
 
6787
                    goto basic_json_parser_50;
 
6788
                }
 
6789
                if (yych <= '9')
 
6790
                {
 
6791
                    goto basic_json_parser_41;
 
6792
                }
 
6793
                goto basic_json_parser_7;
 
6794
basic_json_parser_24:
 
6795
                yyaccept = 1;
 
6796
                yych = *(m_marker = ++m_cursor);
 
6797
                if (yych <= 'D')
 
6798
                {
 
6799
                    if (yych == '.')
 
6800
                    {
 
6801
                        goto basic_json_parser_43;
 
6802
                    }
 
6803
                }
 
6804
                else
 
6805
                {
 
6806
                    if (yych <= 'E')
 
6807
                    {
 
6808
                        goto basic_json_parser_44;
 
6809
                    }
 
6810
                    if (yych == 'e')
 
6811
                    {
 
6812
                        goto basic_json_parser_44;
 
6813
                    }
 
6814
                }
 
6815
basic_json_parser_25:
 
6816
                {
 
6817
                    return token_type::value_number;
 
6818
                }
 
6819
basic_json_parser_26:
 
6820
                yyaccept = 1;
 
6821
                yych = *(m_marker = ++m_cursor);
 
6822
                goto basic_json_parser_42;
 
6823
basic_json_parser_27:
 
6824
                yyaccept = 0;
 
6825
                yych = *(m_marker = ++m_cursor);
 
6826
                if (yych <= 0x0F)
 
6827
                {
 
6828
                    goto basic_json_parser_7;
 
6829
                }
 
6830
                goto basic_json_parser_32;
 
6831
basic_json_parser_28:
 
6832
                ++m_cursor;
 
6833
                {
 
6834
                    return token_type::end_of_input;
 
6835
                }
 
6836
basic_json_parser_30:
 
6837
                yych = *++m_cursor;
 
6838
                goto basic_json_parser_7;
 
6839
basic_json_parser_31:
 
6840
                ++m_cursor;
 
6841
                if (m_limit <= m_cursor)
 
6842
                {
 
6843
                    yyfill();    // LCOV_EXCL_LINE;
 
6844
                }
 
6845
                yych = *m_cursor;
 
6846
basic_json_parser_32:
 
6847
                if (yybm[0 + yych] & 64)
 
6848
                {
 
6849
                    goto basic_json_parser_31;
 
6850
                }
 
6851
                if (yych <= 0x0F)
 
6852
                {
 
6853
                    goto basic_json_parser_33;
 
6854
                }
 
6855
                if (yych <= '"')
 
6856
                {
 
6857
                    goto basic_json_parser_35;
 
6858
                }
 
6859
                goto basic_json_parser_34;
 
6860
basic_json_parser_33:
 
6861
                m_cursor = m_marker;
 
6862
                if (yyaccept == 0)
 
6863
                {
 
6864
                    goto basic_json_parser_7;
 
6865
                }
 
6866
                else
 
6867
                {
 
6868
                    goto basic_json_parser_25;
 
6869
                }
 
6870
basic_json_parser_34:
 
6871
                ++m_cursor;
 
6872
                if (m_limit <= m_cursor)
 
6873
                {
 
6874
                    yyfill();    // LCOV_EXCL_LINE;
 
6875
                }
 
6876
                yych = *m_cursor;
 
6877
                if (yych <= 'e')
 
6878
                {
 
6879
                    if (yych <= '/')
 
6880
                    {
 
6881
                        if (yych == '"')
 
6882
                        {
 
6883
                            goto basic_json_parser_31;
 
6884
                        }
 
6885
                        if (yych <= '.')
 
6886
                        {
 
6887
                            goto basic_json_parser_33;
 
6888
                        }
 
6889
                        goto basic_json_parser_31;
 
6890
                    }
 
6891
                    else
 
6892
                    {
 
6893
                        if (yych <= '\\')
 
6894
                        {
 
6895
                            if (yych <= '[')
 
6896
                            {
 
6897
                                goto basic_json_parser_33;
 
6898
                            }
 
6899
                            goto basic_json_parser_31;
 
6900
                        }
 
6901
                        else
 
6902
                        {
 
6903
                            if (yych == 'b')
 
6904
                            {
 
6905
                                goto basic_json_parser_31;
 
6906
                            }
 
6907
                            goto basic_json_parser_33;
 
6908
                        }
 
6909
                    }
 
6910
                }
 
6911
                else
 
6912
                {
 
6913
                    if (yych <= 'q')
 
6914
                    {
 
6915
                        if (yych <= 'f')
 
6916
                        {
 
6917
                            goto basic_json_parser_31;
 
6918
                        }
 
6919
                        if (yych == 'n')
 
6920
                        {
 
6921
                            goto basic_json_parser_31;
 
6922
                        }
 
6923
                        goto basic_json_parser_33;
 
6924
                    }
 
6925
                    else
 
6926
                    {
 
6927
                        if (yych <= 's')
 
6928
                        {
 
6929
                            if (yych <= 'r')
 
6930
                            {
 
6931
                                goto basic_json_parser_31;
 
6932
                            }
 
6933
                            goto basic_json_parser_33;
 
6934
                        }
 
6935
                        else
 
6936
                        {
 
6937
                            if (yych <= 't')
 
6938
                            {
 
6939
                                goto basic_json_parser_31;
 
6940
                            }
 
6941
                            if (yych <= 'u')
 
6942
                            {
 
6943
                                goto basic_json_parser_37;
 
6944
                            }
 
6945
                            goto basic_json_parser_33;
 
6946
                        }
 
6947
                    }
 
6948
                }
 
6949
basic_json_parser_35:
 
6950
                ++m_cursor;
 
6951
                {
 
6952
                    return token_type::value_string;
 
6953
                }
 
6954
basic_json_parser_37:
 
6955
                ++m_cursor;
 
6956
                if (m_limit <= m_cursor)
 
6957
                {
 
6958
                    yyfill();    // LCOV_EXCL_LINE;
 
6959
                }
 
6960
                yych = *m_cursor;
 
6961
                if (yych <= '@')
 
6962
                {
 
6963
                    if (yych <= '/')
 
6964
                    {
 
6965
                        goto basic_json_parser_33;
 
6966
                    }
 
6967
                    if (yych >= ':')
 
6968
                    {
 
6969
                        goto basic_json_parser_33;
 
6970
                    }
 
6971
                }
 
6972
                else
 
6973
                {
 
6974
                    if (yych <= 'F')
 
6975
                    {
 
6976
                        goto basic_json_parser_38;
 
6977
                    }
 
6978
                    if (yych <= '`')
 
6979
                    {
 
6980
                        goto basic_json_parser_33;
 
6981
                    }
 
6982
                    if (yych >= 'g')
 
6983
                    {
 
6984
                        goto basic_json_parser_33;
 
6985
                    }
 
6986
                }
 
6987
basic_json_parser_38:
 
6988
                ++m_cursor;
 
6989
                if (m_limit <= m_cursor)
 
6990
                {
 
6991
                    yyfill();    // LCOV_EXCL_LINE;
 
6992
                }
 
6993
                yych = *m_cursor;
 
6994
                if (yych <= '@')
 
6995
                {
 
6996
                    if (yych <= '/')
 
6997
                    {
 
6998
                        goto basic_json_parser_33;
 
6999
                    }
 
7000
                    if (yych >= ':')
 
7001
                    {
 
7002
                        goto basic_json_parser_33;
 
7003
                    }
 
7004
                }
 
7005
                else
 
7006
                {
 
7007
                    if (yych <= 'F')
 
7008
                    {
 
7009
                        goto basic_json_parser_39;
 
7010
                    }
 
7011
                    if (yych <= '`')
 
7012
                    {
 
7013
                        goto basic_json_parser_33;
 
7014
                    }
 
7015
                    if (yych >= 'g')
 
7016
                    {
 
7017
                        goto basic_json_parser_33;
 
7018
                    }
 
7019
                }
 
7020
basic_json_parser_39:
 
7021
                ++m_cursor;
 
7022
                if (m_limit <= m_cursor)
 
7023
                {
 
7024
                    yyfill();    // LCOV_EXCL_LINE;
 
7025
                }
 
7026
                yych = *m_cursor;
 
7027
                if (yych <= '@')
 
7028
                {
 
7029
                    if (yych <= '/')
 
7030
                    {
 
7031
                        goto basic_json_parser_33;
 
7032
                    }
 
7033
                    if (yych >= ':')
 
7034
                    {
 
7035
                        goto basic_json_parser_33;
 
7036
                    }
 
7037
                }
 
7038
                else
 
7039
                {
 
7040
                    if (yych <= 'F')
 
7041
                    {
 
7042
                        goto basic_json_parser_40;
 
7043
                    }
 
7044
                    if (yych <= '`')
 
7045
                    {
 
7046
                        goto basic_json_parser_33;
 
7047
                    }
 
7048
                    if (yych >= 'g')
 
7049
                    {
 
7050
                        goto basic_json_parser_33;
 
7051
                    }
 
7052
                }
 
7053
basic_json_parser_40:
 
7054
                ++m_cursor;
 
7055
                if (m_limit <= m_cursor)
 
7056
                {
 
7057
                    yyfill();    // LCOV_EXCL_LINE;
 
7058
                }
 
7059
                yych = *m_cursor;
 
7060
                if (yych <= '@')
 
7061
                {
 
7062
                    if (yych <= '/')
 
7063
                    {
 
7064
                        goto basic_json_parser_33;
 
7065
                    }
 
7066
                    if (yych <= '9')
 
7067
                    {
 
7068
                        goto basic_json_parser_31;
 
7069
                    }
 
7070
                    goto basic_json_parser_33;
 
7071
                }
 
7072
                else
 
7073
                {
 
7074
                    if (yych <= 'F')
 
7075
                    {
 
7076
                        goto basic_json_parser_31;
 
7077
                    }
 
7078
                    if (yych <= '`')
 
7079
                    {
 
7080
                        goto basic_json_parser_33;
 
7081
                    }
 
7082
                    if (yych <= 'f')
 
7083
                    {
 
7084
                        goto basic_json_parser_31;
 
7085
                    }
 
7086
                    goto basic_json_parser_33;
 
7087
                }
 
7088
basic_json_parser_41:
 
7089
                yyaccept = 1;
 
7090
                m_marker = ++m_cursor;
 
7091
                if ((m_limit - m_cursor) < 3)
 
7092
                {
 
7093
                    yyfill();    // LCOV_EXCL_LINE;
 
7094
                }
 
7095
                yych = *m_cursor;
 
7096
basic_json_parser_42:
 
7097
                if (yybm[0 + yych] & 128)
 
7098
                {
 
7099
                    goto basic_json_parser_41;
 
7100
                }
 
7101
                if (yych <= 'D')
 
7102
                {
 
7103
                    if (yych != '.')
 
7104
                    {
 
7105
                        goto basic_json_parser_25;
 
7106
                    }
 
7107
                }
 
7108
                else
 
7109
                {
 
7110
                    if (yych <= 'E')
 
7111
                    {
 
7112
                        goto basic_json_parser_44;
 
7113
                    }
 
7114
                    if (yych == 'e')
 
7115
                    {
 
7116
                        goto basic_json_parser_44;
 
7117
                    }
 
7118
                    goto basic_json_parser_25;
 
7119
                }
 
7120
basic_json_parser_43:
 
7121
                yych = *++m_cursor;
 
7122
                if (yych <= '/')
 
7123
                {
 
7124
                    goto basic_json_parser_33;
 
7125
                }
 
7126
                if (yych <= '9')
 
7127
                {
 
7128
                    goto basic_json_parser_48;
 
7129
                }
 
7130
                goto basic_json_parser_33;
 
7131
basic_json_parser_44:
 
7132
                yych = *++m_cursor;
 
7133
                if (yych <= ',')
 
7134
                {
 
7135
                    if (yych != '+')
 
7136
                    {
 
7137
                        goto basic_json_parser_33;
 
7138
                    }
 
7139
                }
 
7140
                else
 
7141
                {
 
7142
                    if (yych <= '-')
 
7143
                    {
 
7144
                        goto basic_json_parser_45;
 
7145
                    }
 
7146
                    if (yych <= '/')
 
7147
                    {
 
7148
                        goto basic_json_parser_33;
 
7149
                    }
 
7150
                    if (yych <= '9')
 
7151
                    {
 
7152
                        goto basic_json_parser_46;
 
7153
                    }
 
7154
                    goto basic_json_parser_33;
 
7155
                }
 
7156
basic_json_parser_45:
 
7157
                yych = *++m_cursor;
 
7158
                if (yych <= '/')
 
7159
                {
 
7160
                    goto basic_json_parser_33;
 
7161
                }
 
7162
                if (yych >= ':')
 
7163
                {
 
7164
                    goto basic_json_parser_33;
 
7165
                }
 
7166
basic_json_parser_46:
 
7167
                ++m_cursor;
 
7168
                if (m_limit <= m_cursor)
 
7169
                {
 
7170
                    yyfill();    // LCOV_EXCL_LINE;
 
7171
                }
 
7172
                yych = *m_cursor;
 
7173
                if (yych <= '/')
 
7174
                {
 
7175
                    goto basic_json_parser_25;
 
7176
                }
 
7177
                if (yych <= '9')
 
7178
                {
 
7179
                    goto basic_json_parser_46;
 
7180
                }
 
7181
                goto basic_json_parser_25;
 
7182
basic_json_parser_48:
 
7183
                yyaccept = 1;
 
7184
                m_marker = ++m_cursor;
 
7185
                if ((m_limit - m_cursor) < 3)
 
7186
                {
 
7187
                    yyfill();    // LCOV_EXCL_LINE;
 
7188
                }
 
7189
                yych = *m_cursor;
 
7190
                if (yych <= 'D')
 
7191
                {
 
7192
                    if (yych <= '/')
 
7193
                    {
 
7194
                        goto basic_json_parser_25;
 
7195
                    }
 
7196
                    if (yych <= '9')
 
7197
                    {
 
7198
                        goto basic_json_parser_48;
 
7199
                    }
 
7200
                    goto basic_json_parser_25;
 
7201
                }
 
7202
                else
 
7203
                {
 
7204
                    if (yych <= 'E')
 
7205
                    {
 
7206
                        goto basic_json_parser_44;
 
7207
                    }
 
7208
                    if (yych == 'e')
 
7209
                    {
 
7210
                        goto basic_json_parser_44;
 
7211
                    }
 
7212
                    goto basic_json_parser_25;
 
7213
                }
 
7214
basic_json_parser_50:
 
7215
                yyaccept = 1;
 
7216
                yych = *(m_marker = ++m_cursor);
 
7217
                if (yych <= 'D')
 
7218
                {
 
7219
                    if (yych == '.')
 
7220
                    {
 
7221
                        goto basic_json_parser_43;
 
7222
                    }
 
7223
                    goto basic_json_parser_25;
 
7224
                }
 
7225
                else
 
7226
                {
 
7227
                    if (yych <= 'E')
 
7228
                    {
 
7229
                        goto basic_json_parser_44;
 
7230
                    }
 
7231
                    if (yych == 'e')
 
7232
                    {
 
7233
                        goto basic_json_parser_44;
 
7234
                    }
 
7235
                    goto basic_json_parser_25;
 
7236
                }
 
7237
basic_json_parser_51:
 
7238
                yych = *++m_cursor;
 
7239
                if (yych != 'l')
 
7240
                {
 
7241
                    goto basic_json_parser_33;
 
7242
                }
 
7243
                yych = *++m_cursor;
 
7244
                if (yych != 's')
 
7245
                {
 
7246
                    goto basic_json_parser_33;
 
7247
                }
 
7248
                yych = *++m_cursor;
 
7249
                if (yych != 'e')
 
7250
                {
 
7251
                    goto basic_json_parser_33;
 
7252
                }
 
7253
                ++m_cursor;
 
7254
                {
 
7255
                    return token_type::literal_false;
 
7256
                }
 
7257
basic_json_parser_56:
 
7258
                yych = *++m_cursor;
 
7259
                if (yych != 'u')
 
7260
                {
 
7261
                    goto basic_json_parser_33;
 
7262
                }
 
7263
                yych = *++m_cursor;
 
7264
                if (yych != 'e')
 
7265
                {
 
7266
                    goto basic_json_parser_33;
 
7267
                }
 
7268
                ++m_cursor;
 
7269
                {
 
7270
                    return token_type::literal_true;
 
7271
                }
 
7272
basic_json_parser_60:
 
7273
                yych = *++m_cursor;
 
7274
                if (yych != 'l')
 
7275
                {
 
7276
                    goto basic_json_parser_33;
 
7277
                }
 
7278
                yych = *++m_cursor;
 
7279
                if (yych != 'l')
 
7280
                {
 
7281
                    goto basic_json_parser_33;
 
7282
                }
 
7283
                ++m_cursor;
 
7284
                {
 
7285
                    return token_type::literal_null;
 
7286
                }
 
7287
basic_json_parser_64:
 
7288
                yych = *++m_cursor;
 
7289
                if (yych != 0xBF)
 
7290
                {
 
7291
                    goto basic_json_parser_33;
 
7292
                }
 
7293
                ++m_cursor;
 
7294
                {
 
7295
                    return scan();
 
7296
                }
 
7297
            }
 
7298
 
 
7299
 
 
7300
        }
 
7301
 
 
7302
        /// append data from the stream to the internal buffer
 
7303
        void yyfill() noexcept
 
7304
        {
 
7305
            if (not m_stream or not * m_stream)
 
7306
            {
 
7307
                return;
 
7308
            }
 
7309
 
 
7310
            const ssize_t offset_start = m_start - m_content;
 
7311
            const ssize_t offset_marker = m_marker - m_start;
 
7312
            const ssize_t offset_cursor = m_cursor - m_start;
 
7313
 
 
7314
            m_buffer.erase(0, static_cast<size_t>(offset_start));
 
7315
            std::string line;
 
7316
            std::getline(*m_stream, line);
 
7317
            m_buffer += "\n" + line; // add line with newline symbol
 
7318
 
 
7319
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 
7320
            m_start  = m_content;
 
7321
            m_marker = m_start + offset_marker;
 
7322
            m_cursor = m_start + offset_cursor;
 
7323
            m_limit  = m_start + m_buffer.size() - 1;
 
7324
        }
 
7325
 
 
7326
        /// return string representation of last read token
 
7327
        string_t get_token() const noexcept
 
7328
        {
 
7329
            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
 
7330
                            static_cast<size_t>(m_cursor - m_start));
 
7331
        }
 
7332
 
 
7333
        /*!
 
7334
        @brief return string value for string tokens
 
7335
 
 
7336
        The function iterates the characters between the opening and closing
 
7337
        quotes of the string value. The complete string is the range
 
7338
        [m_start,m_cursor). Consequently, we iterate from m_start+1 to
 
7339
        m_cursor-1.
 
7340
 
 
7341
        We differentiate two cases:
 
7342
 
 
7343
        1. Escaped characters. In this case, a new character is constructed
 
7344
           according to the nature of the escape. Some escapes create new
 
7345
           characters (e.g., @c "\\n" is replaced by @c "\n"), some are copied
 
7346
           as is (e.g., @c "\\\\"). Furthermore, Unicode escapes of the shape
 
7347
           @c "\\uxxxx" need special care. In this case, to_unicode takes care
 
7348
           of the construction of the values.
 
7349
        2. Unescaped characters are copied as is.
 
7350
 
 
7351
        @return string value of current token without opening and closing quotes
 
7352
        @throw std::out_of_range if to_unicode fails
 
7353
        */
 
7354
        string_t get_string() const
 
7355
        {
 
7356
            string_t result;
 
7357
            result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
 
7358
 
 
7359
            // iterate the result between the quotes
 
7360
            for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
 
7361
            {
 
7362
                // process escaped characters
 
7363
                if (*i == '\\')
 
7364
                {
 
7365
                    // read next character
 
7366
                    ++i;
 
7367
 
 
7368
                    switch (*i)
 
7369
                    {
 
7370
                        // the default escapes
 
7371
                        case 't':
 
7372
                        {
 
7373
                            result += "\t";
 
7374
                            break;
 
7375
                        }
 
7376
                        case 'b':
 
7377
                        {
 
7378
                            result += "\b";
 
7379
                            break;
 
7380
                        }
 
7381
                        case 'f':
 
7382
                        {
 
7383
                            result += "\f";
 
7384
                            break;
 
7385
                        }
 
7386
                        case 'n':
 
7387
                        {
 
7388
                            result += "\n";
 
7389
                            break;
 
7390
                        }
 
7391
                        case 'r':
 
7392
                        {
 
7393
                            result += "\r";
 
7394
                            break;
 
7395
                        }
 
7396
                        case '\\':
 
7397
                        {
 
7398
                            result += "\\";
 
7399
                            break;
 
7400
                        }
 
7401
                        case '/':
 
7402
                        {
 
7403
                            result += "/";
 
7404
                            break;
 
7405
                        }
 
7406
                        case '"':
 
7407
                        {
 
7408
                            result += "\"";
 
7409
                            break;
 
7410
                        }
 
7411
 
 
7412
                        // unicode
 
7413
                        case 'u':
 
7414
                        {
 
7415
                            // get code xxxx from uxxxx
 
7416
                            auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
 
7417
                                                          4).c_str(), nullptr, 16);
 
7418
 
 
7419
                            // check if codepoint is a high surrogate
 
7420
                            if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
 
7421
                            {
 
7422
                                // make sure there is a subsequent unicode
 
7423
                                if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
 
7424
                                {
 
7425
                                    throw std::invalid_argument("missing low surrogate");
 
7426
                                }
 
7427
 
 
7428
                                // get code yyyy from uxxxx\uyyyy
 
7429
                                auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
 
7430
                                                               (i + 7), 4).c_str(), nullptr, 16);
 
7431
                                result += to_unicode(codepoint, codepoint2);
 
7432
                                // skip the next 10 characters (xxxx\uyyyy)
 
7433
                                i += 10;
 
7434
                            }
 
7435
                            else
 
7436
                            {
 
7437
                                // add unicode character(s)
 
7438
                                result += to_unicode(codepoint);
 
7439
                                // skip the next four characters (xxxx)
 
7440
                                i += 4;
 
7441
                            }
 
7442
                            break;
 
7443
                        }
 
7444
                    }
 
7445
                }
 
7446
                else
 
7447
                {
 
7448
                    // all other characters are just copied to the end of the
 
7449
                    // string
 
7450
                    result.append(1, static_cast<typename string_t::value_type>(*i));
 
7451
                }
 
7452
            }
 
7453
 
 
7454
            return result;
 
7455
        }
 
7456
 
 
7457
        /*!
 
7458
        @brief return number value for number tokens
 
7459
 
 
7460
        This function translates the last token into a floating point number.
 
7461
        The pointer m_start points to the beginning of the parsed number. We
 
7462
        pass this pointer to std::strtod which sets endptr to the first
 
7463
        character past the converted number. If this pointer is not the same as
 
7464
        m_cursor, then either more or less characters have been used during the
 
7465
        comparison. This can happen for inputs like "01" which will be treated
 
7466
        like number 0 followed by number 1.
 
7467
 
 
7468
        @return the result of the number conversion or NAN if the conversion
 
7469
        read past the current token. The latter case needs to be treated by the
 
7470
        caller function.
 
7471
 
 
7472
        @throw std::range_error if passed value is out of range
 
7473
        */
 
7474
        long double get_number() const
 
7475
        {
 
7476
            // conversion
 
7477
            typename string_t::value_type* endptr;
 
7478
            const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
 
7479
                                                &endptr);
 
7480
 
 
7481
            // return float_val if the whole number was translated and NAN
 
7482
            // otherwise
 
7483
            return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
 
7484
        }
 
7485
 
 
7486
      private:
 
7487
        /// optional input stream
 
7488
        std::istream* m_stream;
 
7489
        /// the buffer
 
7490
        string_t m_buffer;
 
7491
        /// the buffer pointer
 
7492
        const lexer_char_t* m_content = nullptr;
 
7493
        /// pointer to the beginning of the current symbol
 
7494
        const lexer_char_t* m_start = nullptr;
 
7495
        /// pointer for backtracking information
 
7496
        const lexer_char_t* m_marker = nullptr;
 
7497
        /// pointer to the current symbol
 
7498
        const lexer_char_t* m_cursor = nullptr;
 
7499
        /// pointer to the end of the buffer
 
7500
        const lexer_char_t* m_limit = nullptr;
 
7501
    };
 
7502
 
 
7503
    /*!
 
7504
    @brief syntax analysis
 
7505
 
 
7506
    This class implements a recursive decent parser.
 
7507
    */
 
7508
    class parser
 
7509
    {
 
7510
      public:
 
7511
        /// constructor for strings
 
7512
        parser(const string_t& s, parser_callback_t cb = nullptr)
 
7513
            : callback(cb), m_lexer(s)
 
7514
        {
 
7515
            // read first token
 
7516
            get_token();
 
7517
        }
 
7518
 
 
7519
        /// a parser reading from an input stream
 
7520
        parser(std::istream& _is, parser_callback_t cb = nullptr)
 
7521
            : callback(cb), m_lexer(&_is)
 
7522
        {
 
7523
            // read first token
 
7524
            get_token();
 
7525
        }
 
7526
 
 
7527
        /// public parser interface
 
7528
        basic_json parse()
 
7529
        {
 
7530
            basic_json result = parse_internal(true);
 
7531
 
 
7532
            expect(lexer::token_type::end_of_input);
 
7533
 
 
7534
            // return parser result and replace it with null in case the
 
7535
            // top-level value was discarded by the callback function
 
7536
            return result.is_discarded() ? basic_json() : result;
 
7537
        }
 
7538
 
 
7539
      private:
 
7540
        /// the actual parser
 
7541
        basic_json parse_internal(bool keep)
 
7542
        {
 
7543
            auto result = basic_json(value_t::discarded);
 
7544
 
 
7545
            switch (last_token)
 
7546
            {
 
7547
                case lexer::token_type::begin_object:
 
7548
                {
 
7549
                    if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
 
7550
                    {
 
7551
                        // explicitly set result to object to cope with {}
 
7552
                        result.m_type = value_t::object;
 
7553
                        result.m_value = json_value(value_t::object);
 
7554
                    }
 
7555
 
 
7556
                    // read next token
 
7557
                    get_token();
 
7558
 
 
7559
                    // closing } -> we are done
 
7560
                    if (last_token == lexer::token_type::end_object)
 
7561
                    {
 
7562
                        get_token();
 
7563
                        if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
 
7564
                        {
 
7565
                            result = basic_json(value_t::discarded);
 
7566
                        }
 
7567
                        return result;
 
7568
                    }
 
7569
 
 
7570
                    // no comma is expected here
 
7571
                    unexpect(lexer::token_type::value_separator);
 
7572
 
 
7573
                    // otherwise: parse key-value pairs
 
7574
                    do
 
7575
                    {
 
7576
                        // ugly, but could be fixed with loop reorganization
 
7577
                        if (last_token == lexer::token_type::value_separator)
 
7578
                        {
 
7579
                            get_token();
 
7580
                        }
 
7581
 
 
7582
                        // store key
 
7583
                        expect(lexer::token_type::value_string);
 
7584
                        const auto key = m_lexer.get_string();
 
7585
 
 
7586
                        bool keep_tag = false;
 
7587
                        if (keep)
 
7588
                        {
 
7589
                            if (callback)
 
7590
                            {
 
7591
                                basic_json k(key);
 
7592
                                keep_tag = callback(depth, parse_event_t::key, k);
 
7593
                            }
 
7594
                            else
 
7595
                            {
 
7596
                                keep_tag = true;
 
7597
                            }
 
7598
                        }
 
7599
 
 
7600
                        // parse separator (:)
 
7601
                        get_token();
 
7602
                        expect(lexer::token_type::name_separator);
 
7603
 
 
7604
                        // parse and add value
 
7605
                        get_token();
 
7606
                        auto value = parse_internal(keep);
 
7607
                        if (keep and keep_tag and not value.is_discarded())
 
7608
                        {
 
7609
                            result[key] = std::move(value);
 
7610
                        }
 
7611
                    }
 
7612
                    while (last_token == lexer::token_type::value_separator);
 
7613
 
 
7614
                    // closing }
 
7615
                    expect(lexer::token_type::end_object);
 
7616
                    get_token();
 
7617
                    if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
 
7618
                    {
 
7619
                        result = basic_json(value_t::discarded);
 
7620
                    }
 
7621
 
 
7622
                    return result;
 
7623
                }
 
7624
 
 
7625
                case lexer::token_type::begin_array:
 
7626
                {
 
7627
                    if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
 
7628
                    {
 
7629
                        // explicitly set result to object to cope with []
 
7630
                        result.m_type = value_t::array;
 
7631
                        result.m_value = json_value(value_t::array);
 
7632
                    }
 
7633
 
 
7634
                    // read next token
 
7635
                    get_token();
 
7636
 
 
7637
                    // closing ] -> we are done
 
7638
                    if (last_token == lexer::token_type::end_array)
 
7639
                    {
 
7640
                        get_token();
 
7641
                        if (callback and not callback(--depth, parse_event_t::array_end, result))
 
7642
                        {
 
7643
                            result = basic_json(value_t::discarded);
 
7644
                        }
 
7645
                        return result;
 
7646
                    }
 
7647
 
 
7648
                    // no comma is expected here
 
7649
                    unexpect(lexer::token_type::value_separator);
 
7650
 
 
7651
                    // otherwise: parse values
 
7652
                    do
 
7653
                    {
 
7654
                        // ugly, but could be fixed with loop reorganization
 
7655
                        if (last_token == lexer::token_type::value_separator)
 
7656
                        {
 
7657
                            get_token();
 
7658
                        }
 
7659
 
 
7660
                        // parse value
 
7661
                        auto value = parse_internal(keep);
 
7662
                        if (keep and not value.is_discarded())
 
7663
                        {
 
7664
                            result.push_back(std::move(value));
 
7665
                        }
 
7666
                    }
 
7667
                    while (last_token == lexer::token_type::value_separator);
 
7668
 
 
7669
                    // closing ]
 
7670
                    expect(lexer::token_type::end_array);
 
7671
                    get_token();
 
7672
                    if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
 
7673
                    {
 
7674
                        result = basic_json(value_t::discarded);
 
7675
                    }
 
7676
 
 
7677
                    return result;
 
7678
                }
 
7679
 
 
7680
                case lexer::token_type::literal_null:
 
7681
                {
 
7682
                    get_token();
 
7683
                    result.m_type = value_t::null;
 
7684
                    break;
 
7685
                }
 
7686
 
 
7687
                case lexer::token_type::value_string:
 
7688
                {
 
7689
                    const auto s = m_lexer.get_string();
 
7690
                    get_token();
 
7691
                    result = basic_json(s);
 
7692
                    break;
 
7693
                }
 
7694
 
 
7695
                case lexer::token_type::literal_true:
 
7696
                {
 
7697
                    get_token();
 
7698
                    result.m_type = value_t::boolean;
 
7699
                    result.m_value = true;
 
7700
                    break;
 
7701
                }
 
7702
 
 
7703
                case lexer::token_type::literal_false:
 
7704
                {
 
7705
                    get_token();
 
7706
                    result.m_type = value_t::boolean;
 
7707
                    result.m_value = false;
 
7708
                    break;
 
7709
                }
 
7710
 
 
7711
                case lexer::token_type::value_number:
 
7712
                {
 
7713
                    auto float_val = m_lexer.get_number();
 
7714
 
 
7715
                    // NAN is returned if token could not be translated
 
7716
                    // completely
 
7717
                    if (std::isnan(float_val))
 
7718
                    {
 
7719
                        throw std::invalid_argument(std::string("parse error - ") +
 
7720
                                                    m_lexer.get_token() + " is not a number");
 
7721
                    }
 
7722
 
 
7723
                    get_token();
 
7724
 
 
7725
                    // check if conversion loses precision
 
7726
                    const auto int_val = static_cast<number_integer_t>(float_val);
 
7727
                    if (approx(float_val, static_cast<long double>(int_val)))
 
7728
                    {
 
7729
                        // we would not lose precision -> return int
 
7730
                        result.m_type = value_t::number_integer;
 
7731
                        result.m_value = int_val;
 
7732
                    }
 
7733
                    else
 
7734
                    {
 
7735
                        // we would lose precision -> return float
 
7736
                        result.m_type = value_t::number_float;
 
7737
                        result.m_value = static_cast<number_float_t>(float_val);
 
7738
                    }
 
7739
                    break;
 
7740
                }
 
7741
 
 
7742
                default:
 
7743
                {
 
7744
                    // the last token was unexpected
 
7745
                    unexpect(last_token);
 
7746
                }
 
7747
            }
 
7748
 
 
7749
            if (keep and callback and not callback(depth, parse_event_t::value, result))
 
7750
            {
 
7751
                result = basic_json(value_t::discarded);
 
7752
            }
 
7753
            return result;
 
7754
        }
 
7755
 
 
7756
        /// get next token from lexer
 
7757
        typename lexer::token_type get_token()
 
7758
        {
 
7759
            last_token = m_lexer.scan();
 
7760
            return last_token;
 
7761
        }
 
7762
 
 
7763
        void expect(typename lexer::token_type t) const
 
7764
        {
 
7765
            if (t != last_token)
 
7766
            {
 
7767
                std::string error_msg = "parse error - unexpected ";
 
7768
                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
 
7769
                              lexer::token_type_name(last_token));
 
7770
                error_msg += "; expected " + lexer::token_type_name(t);
 
7771
                throw std::invalid_argument(error_msg);
 
7772
            }
 
7773
        }
 
7774
 
 
7775
        void unexpect(typename lexer::token_type t) const
 
7776
        {
 
7777
            if (t == last_token)
 
7778
            {
 
7779
                std::string error_msg = "parse error - unexpected ";
 
7780
                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
 
7781
                              lexer::token_type_name(last_token));
 
7782
                throw std::invalid_argument(error_msg);
 
7783
            }
 
7784
        }
 
7785
 
 
7786
      private:
 
7787
        /// current level of recursion
 
7788
        int depth = 0;
 
7789
        /// callback function
 
7790
        parser_callback_t callback;
 
7791
        /// the type of the last read token
 
7792
        typename lexer::token_type last_token = lexer::token_type::uninitialized;
 
7793
        /// the lexer
 
7794
        lexer m_lexer;
 
7795
    };
 
7796
};
 
7797
 
 
7798
 
 
7799
/////////////
 
7800
// presets //
 
7801
/////////////
 
7802
 
 
7803
/*!
 
7804
@brief default JSON class
 
7805
 
 
7806
This type is the default specialization of the @ref basic_json class which uses
 
7807
the standard template types.
 
7808
 
 
7809
@since version 1.0.0
 
7810
*/
 
7811
using json = basic_json<>;
 
7812
}
 
7813
 
 
7814
 
 
7815
/////////////////////////
 
7816
// nonmember functions //
 
7817
/////////////////////////
 
7818
 
 
7819
// specialization of std::swap, and std::hash
 
7820
namespace std
 
7821
{
 
7822
/*!
 
7823
@brief exchanges the values of two JSON objects
 
7824
 
 
7825
@since version 1.0.0
 
7826
*/
 
7827
template <>
 
7828
inline void swap(nlohmann::json& j1,
 
7829
                 nlohmann::json& j2) noexcept(
 
7830
                     is_nothrow_move_constructible<nlohmann::json>::value and
 
7831
                     is_nothrow_move_assignable<nlohmann::json>::value
 
7832
                 )
 
7833
{
 
7834
    j1.swap(j2);
 
7835
}
 
7836
 
 
7837
/// hash value for JSON objects
 
7838
template <>
 
7839
struct hash<nlohmann::json>
 
7840
{
 
7841
    /*!
 
7842
    @brief return a hash value for a JSON object
 
7843
 
 
7844
    @since version 1.0.0
 
7845
    */
 
7846
    std::size_t operator()(const nlohmann::json& j) const
 
7847
    {
 
7848
        // a naive hashing via the string representation
 
7849
        const auto& h = hash<nlohmann::json::string_t>();
 
7850
        return h(j.dump());
 
7851
    }
 
7852
};
 
7853
}
 
7854
 
 
7855
/*!
 
7856
@brief user-defined string literal for JSON values
 
7857
 
 
7858
This operator implements a user-defined string literal for JSON objects. It can
 
7859
be used by adding \p "_json" to a string literal and returns a JSON object if
 
7860
no parse error occurred.
 
7861
 
 
7862
@param[in] s  a string representation of a JSON object
 
7863
@return a JSON object
 
7864
 
 
7865
@since version 1.0.0
 
7866
*/
 
7867
inline nlohmann::json operator "" _json(const char* s, std::size_t)
 
7868
{
 
7869
    return nlohmann::json::parse(reinterpret_cast<nlohmann::json::string_t::value_type*>
 
7870
                                 (const_cast<char*>(s)));
 
7871
}
 
7872
 
 
7873
#endif