json.hpp.re2c 314 KB
Newer Older
1
2
3
/*
    __ _____ _____ _____
 __|  |   __|     |   | |  JSON for Modern C++
Niels's avatar
Niels committed
4
|  |  |__   |  |  | | | |  version 2.0.2
5
6
7
|_____|_____|_____|_|___|  https://github.com/nlohmann/json

Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.

Permission is hereby  granted, free of charge, to any  person obtaining a copy
of this software and associated  documentation files (the "Software"), to deal
in the Software  without restriction, including without  limitation the rights
to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Niels's avatar
Niels committed
27
28
*/

Niels's avatar
Niels committed
29
30
#ifndef NLOHMANN_JSON_HPP
#define NLOHMANN_JSON_HPP
Niels's avatar
cleanup  
Niels committed
31
32

#include <algorithm>
33
#include <array>
Niels's avatar
Niels committed
34
#include <cassert>
Niels's avatar
Niels committed
35
#include <ciso646>
Niels's avatar
Niels committed
36
#include <cmath>
Niels's avatar
Niels committed
37
#include <cstddef>
38
#include <cstdint>
Niels's avatar
Niels committed
39
#include <cstdlib>
Niels's avatar
cleanup  
Niels committed
40
41
#include <functional>
#include <initializer_list>
Niels's avatar
Niels committed
42
#include <iomanip>
Niels's avatar
cleanup  
Niels committed
43
44
45
#include <iostream>
#include <iterator>
#include <limits>
Niels's avatar
Niels committed
46
#include <locale>
Niels's avatar
cleanup  
Niels committed
47
48
#include <map>
#include <memory>
Niels's avatar
Niels committed
49
#include <numeric>
Niels's avatar
Niels committed
50
#include <sstream>
Niels's avatar
Niels committed
51
#include <stdexcept>
Niels's avatar
cleanup  
Niels committed
52
53
54
55
56
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

Niels's avatar
Niels committed
57
58
59
// exclude unsupported compilers
#if defined(__clang__)
    #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
Niels's avatar
math...    
Niels committed
60
    #if CLANG_VERSION < 30400
Niels's avatar
Niels committed
61
62
        #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
    #endif
Niels's avatar
Niels committed
63
#elif defined(__GNUC__)
Niels's avatar
Niels committed
64
    #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
Niels's avatar
math...    
Niels committed
65
    #if GCC_VERSION < 40900
Niels's avatar
Niels committed
66
67
68
69
        #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
    #endif
#endif

70
71
72
73
74
75
// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wfloat-equal"
#endif

Niels's avatar
cleanup  
Niels committed
76
/*!
Niels's avatar
Niels committed
77
@brief namespace for Niels Lohmann
Niels's avatar
cleanup  
Niels committed
78
@see https://github.com/nlohmann
Niels's avatar
Niels committed
79
@since version 1.0.0
Niels's avatar
cleanup  
Niels committed
80
81
82
83
*/
namespace nlohmann
{

Niels's avatar
Niels committed
84

85
86
/*!
@brief unnamed namespace with internal helper functions
Niels's avatar
Niels committed
87
@since version 1.0.0
88
89
*/
namespace
Niels's avatar
Niels committed
90
{
91
92
/*!
@brief Helper to determine whether there's a key_type for T.
Niels's avatar
Niels committed
93
94
95
96
97

Thus helper is used to tell associative containers apart from other containers
such as sequence containers. For instance, `std::map` passes the test as it
contains a `mapped_type`, whereas `std::vector` fails the test.

98
@sa http://stackoverflow.com/a/7728728/266378
Niels's avatar
Niels committed
99
@since version 1.0.0
100
*/
Niels's avatar
Niels committed
101
template<typename T>
Niels's avatar
Niels committed
102
struct has_mapped_type
Niels's avatar
Niels committed
103
104
{
  private:
Niels's avatar
Niels committed
105
    template<typename C> static char test(typename C::mapped_type*);
Niels's avatar
Niels committed
106
    template<typename C> static char (&test(...))[2];
Niels's avatar
Niels committed
107
  public:
Niels's avatar
Niels committed
108
    static constexpr bool value = sizeof(test<T>(0)) == 1;
Niels's avatar
Niels committed
109
};
110

111
112
/*!
@brief helper class to create locales with decimal point
Niels's avatar
Niels committed
113
114
115
116
117
118
119

This struct is used a default locale during the JSON serialization. JSON
requires the decimal point to be `.`, so this function overloads the
`do_decimal_point()` function to return `.`. This function is called by
float-to-string conversions to retrieve the decimal separator between integer
and fractional parts.

120
@sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315
Niels's avatar
Niels committed
121
@since version 2.0.0
122
*/
Niels's avatar
Niels committed
123
struct DecimalSeparator : std::numpunct<char>
124
125
126
127
128
129
130
{
    char do_decimal_point() const
    {
        return '.';
    }
};

Niels's avatar
Niels committed
131
}
Niels's avatar
Niels committed
132

Niels's avatar
cleanup  
Niels committed
133
/*!
Niels's avatar
Niels committed
134
@brief a class to store JSON values
Niels's avatar
cleanup  
Niels committed
135

Niels's avatar
Niels committed
136
@tparam ObjectType type for JSON objects (`std::map` by default; will be used
Niels's avatar
Niels committed
137
in @ref object_t)
Niels's avatar
Niels committed
138
@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
Niels's avatar
Niels committed
139
in @ref array_t)
Niels's avatar
Niels committed
140
@tparam StringType type for JSON strings and object keys (`std::string` by
Niels's avatar
Niels committed
141
default; will be used in @ref string_t)
Niels's avatar
Niels committed
142
@tparam BooleanType type for JSON booleans (`bool` by default; will be used
Niels's avatar
Niels committed
143
in @ref boolean_t)
Niels's avatar
Niels committed
144
@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
Niels's avatar
Niels committed
145
default; will be used in @ref number_integer_t)
Niels's avatar
Niels committed
146
147
@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
`uint64_t` by default; will be used in @ref number_unsigned_t)
Niels's avatar
Niels committed
148
@tparam NumberFloatType type for JSON floating-point numbers (`double` by
Niels's avatar
Niels committed
149
default; will be used in @ref number_float_t)
Niels's avatar
Niels committed
150
@tparam AllocatorType type of the allocator to use (`std::allocator` by
Niels's avatar
Niels committed
151
default)
Niels's avatar
Niels committed
152

Niels's avatar
Niels committed
153
154
@requirement The class satisfies the following concept requirements:
- Basic
Niels's avatar
Niels committed
155
156
157
158
159
 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
   JSON values can be default constructed. The result will be a JSON null value.
 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
   A JSON value can be constructed from an rvalue argument.
 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
Niels's avatar
Niels committed
160
   A JSON value can be copy-constructed from an lvalue expression.
Niels's avatar
Niels committed
161
162
163
164
165
166
 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
   A JSON value van be assigned from an rvalue argument.
 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
   A JSON value can be copy-assigned from an lvalue expression.
 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
   JSON values can be destructed.
Niels's avatar
Niels committed
167
- Layout
Niels's avatar
Niels committed
168
169
170
171
172
 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
   JSON values have
   [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
   All non-static data members are private and standard layout types, the class
   has no virtual functions or (virtual) base classes.
Niels's avatar
Niels committed
173
- Library-wide
Niels's avatar
Niels committed
174
175
176
177
178
179
180
181
182
183
184
185
 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
   JSON values can be compared with `==`, see @ref
   operator==(const_reference,const_reference).
 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
   JSON values can be compared with `<`, see @ref
   operator<(const_reference,const_reference).
 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
   other compatible types, using unqualified function call @ref swap().
 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
   JSON values can be compared against `std::nullptr_t` objects which are used
   to model the `null` value.
Niels's avatar
Niels committed
186
- Container
Niels's avatar
Niels committed
187
188
189
190
191
 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
   JSON values can be used like STL containers and provide iterator access.
 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
   JSON values can be used like STL containers and provide reverse iterator
   access.
Niels's avatar
Niels committed
192

193
194
195
196
197
198
199
@invariant The member variables @a m_value and @a m_type have the following
relationship:
- If `m_type == value_t::object`, then `m_value.object != nullptr`.
- If `m_type == value_t::array`, then `m_value.array != nullptr`.
- If `m_type == value_t::string`, then `m_value.string != nullptr`.
The invariants are checked by member function assert_invariant().

Niels's avatar
Niels committed
200
@internal
Niels's avatar
Niels committed
201
@note ObjectType trick from http://stackoverflow.com/a/9860911
Niels's avatar
Niels committed
202
@endinternal
Niels's avatar
Niels committed
203

204
205
@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
Format](http://rfc7159.net/rfc7159)
Niels's avatar
Niels committed
206

Niels's avatar
Niels committed
207
@since version 1.0.0
Niels's avatar
Niels committed
208
209

@nosubgrouping
Niels's avatar
cleanup  
Niels committed
210
211
212
213
214
215
*/
template <
    template<typename U, typename V, typename... Args> class ObjectType = std::map,
    template<typename U, typename... Args> class ArrayType = std::vector,
    class StringType = std::string,
    class BooleanType = bool,
216
217
    class NumberIntegerType = std::int64_t,
    class NumberUnsignedType = std::uint64_t,
Niels's avatar
Niels committed
218
    class NumberFloatType = double,
Niels's avatar
Niels committed
219
    template<typename U> class AllocatorType = std::allocator
Niels's avatar
cleanup  
Niels committed
220
221
222
    >
class basic_json
{
223
224
  private:
    /// workaround type for MSVC
Niels's avatar
Niels committed
225
226
    using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
          BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
Niels's avatar
Niels committed
227
          AllocatorType>;
228
229

  public:
Niels's avatar
Niels committed
230
231
232
    // forward declarations
    template<typename Base> class json_reverse_iterator;
    class json_pointer;
233

Niels's avatar
cleanup  
Niels committed
234
235
236
237
    /////////////////////
    // container types //
    /////////////////////

Niels's avatar
Niels committed
238
    /// @name container types
Niels's avatar
Niels committed
239
240
    /// The canonic container types to use @ref basic_json like any other STL
    /// container.
Niels's avatar
Niels committed
241
242
    /// @{

Niels's avatar
Niels committed
243
    /// the type of elements in a basic_json container
Niels's avatar
cleanup  
Niels committed
244
    using value_type = basic_json;
Niels's avatar
Niels committed
245

Niels's avatar
Niels committed
246
    /// the type of an element reference
Niels's avatar
Niels committed
247
    using reference = value_type&;
Niels's avatar
Niels committed
248
    /// the type of an element const reference
Niels's avatar
Niels committed
249
    using const_reference = const value_type&;
Niels's avatar
Niels committed
250

Niels's avatar
Niels committed
251
    /// a type to represent differences between iterators
Niels's avatar
Niels committed
252
    using difference_type = std::ptrdiff_t;
Niels's avatar
Niels committed
253
    /// a type to represent container sizes
Niels's avatar
Niels committed
254
255
256
    using size_type = std::size_t;

    /// the allocator type
Niels's avatar
Niels committed
257
    using allocator_type = AllocatorType<basic_json>;
Niels's avatar
Niels committed
258

Niels's avatar
cleanup  
Niels committed
259
    /// the type of an element pointer
Niels's avatar
Niels committed
260
    using pointer = typename std::allocator_traits<allocator_type>::pointer;
Niels's avatar
cleanup  
Niels committed
261
    /// the type of an element const pointer
Niels's avatar
Niels committed
262
    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
Niels's avatar
Niels committed
263

Niels's avatar
Niels committed
264
265
266
267
268
    /// an iterator for a basic_json container
    class iterator;
    /// a const iterator for a basic_json container
    class const_iterator;
    /// a reverse iterator for a basic_json container
269
    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
Niels's avatar
Niels committed
270
    /// a const reverse iterator for a basic_json container
271
    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
Niels's avatar
Niels committed
272

Niels's avatar
Niels committed
273
274
275
    /// @}


Niels's avatar
Niels committed
276
277
278
    /*!
    @brief returns the allocator associated with the container
    */
279
    static allocator_type get_allocator()
Niels's avatar
Niels committed
280
281
282
283
284
    {
        return allocator_type();
    }


Niels's avatar
cleanup  
Niels committed
285
286
287
288
    ///////////////////////////
    // JSON value data types //
    ///////////////////////////

Niels's avatar
Niels committed
289
    /// @name JSON value data types
Niels's avatar
Niels committed
290
291
    /// The data types to store a JSON value. These types are derived from
    /// the template arguments passed to class @ref basic_json.
Niels's avatar
Niels committed
292
293
    /// @{

Niels's avatar
Niels committed
294
295
296
297
298
299
300
301
    /*!
    @brief a type for an object

    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
    > An object is an unordered collection of zero or more name/value pairs,
    > where a name is a string and a value is a string, number, boolean, null,
    > object, or array.

Niels's avatar
Niels committed
302
303
304
305
306
    To store objects in C++, a type is defined by the template parameters
    described below.

    @tparam ObjectType  the container to store objects (e.g., `std::map` or
    `std::unordered_map`)
Niels's avatar
Niels committed
307
308
    @tparam StringType the type of the keys or names (e.g., `std::string`).
    The comparison function `std::less<StringType>` is used to order elements
Niels's avatar
Niels committed
309
310
311
    inside the container.
    @tparam AllocatorType the allocator to use for objects (e.g.,
    `std::allocator`)
Niels's avatar
Niels committed
312
313
314
315

    #### Default type

    With the default values for @a ObjectType (`std::map`), @a StringType
Niels's avatar
Niels committed
316
317
    (`std::string`), and @a AllocatorType (`std::allocator`), the default
    value for @a object_t is:
Niels's avatar
Niels committed
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

    @code {.cpp}
    std::map<
      std::string, // key_type
      basic_json, // value_type
      std::less<std::string>, // key_compare
      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
    >
    @endcode

    #### Behavior

    The choice of @a object_t influences the behavior of the JSON class. With
    the default type, objects have the following behavior:

    - When all names are unique, objects will be interoperable in the sense
Niels's avatar
Niels committed
334
335
      that all software implementations receiving that object will agree on
      the name-value mappings.
Niels's avatar
Niels committed
336
337
338
339
340
    - When the names within an object are not unique, later stored name/value
      pairs overwrite previously stored name/value pairs, leaving the used
      names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
      be treated as equal and both stored as `{"key": 1}`.
    - Internally, name/value pairs are stored in lexicographical order of the
Niels's avatar
Niels committed
341
342
343
      names. Objects will also be serialized (see @ref dump) in this order.
      For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
      and serialized as `{"a": 2, "b": 1}`.
Niels's avatar
Niels committed
344
345
346
347
348
349
350
351
352
353
354
355
    - When comparing objects, the order of the name/value pairs is irrelevant.
      This makes objects interoperable in the sense that they will not be
      affected by these differences. For instance, `{"b": 1, "a": 2}` and
      `{"a": 2, "b": 1}` will be treated as equal.

    #### Limits

    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
    > An implementation may set limits on the maximum depth of nesting.

    In this class, the object's limit of nesting is not constraint explicitly.
    However, a maximum depth of nesting may be introduced by the compiler or
Niels's avatar
Niels committed
356
357
    runtime environment. A theoretical limit can be queried by calling the
    @ref max_size function of a JSON object.
Niels's avatar
Niels committed
358
359
360

    #### Storage

361
    Objects are stored as pointers in a @ref basic_json type. That is, for any
Niels's avatar
Niels committed
362
363
    access to object values, a pointer of type `object_t*` must be
    dereferenced.
Niels's avatar
Niels committed
364

365
366
    @sa @ref array_t -- type for an array value

Niels's avatar
Niels committed
367
    @since version 1.0.0
Niels's avatar
Niels committed
368

Niels's avatar
Niels committed
369
370
371
372
373
    @note The order name/value pairs are added to the object is *not*
    preserved by the library. Therefore, iterating an object may return
    name/value pairs in a different order than they were originally stored. In
    fact, keys will be traversed in alphabetical order as `std::map` with
    `std::less` is used by default. Please note this behavior conforms to [RFC
Niels's avatar
Niels committed
374
375
    7159](http://rfc7159.net/rfc7159), because any order implements the
    specified "unordered" nature of JSON objects.
Niels's avatar
Niels committed
376
    */
Niels's avatar
Niels committed
377
378
379
380
381
    using object_t = ObjectType<StringType,
          basic_json,
          std::less<StringType>,
          AllocatorType<std::pair<const StringType,
          basic_json>>>;
Niels's avatar
Niels committed
382
383
384
385
386
387
388

    /*!
    @brief a type for an array

    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
    > An array is an ordered sequence of zero or more values.

Niels's avatar
Niels committed
389
390
391
392
393
    To store objects in C++, a type is defined by the template parameters
    explained below.

    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
    `std::list`)
Niels's avatar
Niels committed
394
    @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
Niels's avatar
Niels committed
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

    #### Default type

    With the default values for @a ArrayType (`std::vector`) and @a
    AllocatorType (`std::allocator`), the default value for @a array_t is:

    @code {.cpp}
    std::vector<
      basic_json, // value_type
      std::allocator<basic_json> // allocator_type
    >
    @endcode

    #### Limits

    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
    > An implementation may set limits on the maximum depth of nesting.

    In this class, the array's limit of nesting is not constraint explicitly.
    However, a maximum depth of nesting may be introduced by the compiler or
Niels's avatar
Niels committed
415
416
    runtime environment. A theoretical limit can be queried by calling the
    @ref max_size function of a JSON array.
Niels's avatar
Niels committed
417
418
419

    #### Storage

420
    Arrays are stored as pointers in a @ref basic_json type. That is, for any
Niels's avatar
Niels committed
421
    access to array values, a pointer of type `array_t*` must be dereferenced.
422
423
424

    @sa @ref object_t -- type for an object value

Niels's avatar
Niels committed
425
    @since version 1.0.0
Niels's avatar
Niels committed
426
    */
Niels's avatar
Niels committed
427
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
Niels's avatar
Niels committed
428
429
430
431
432
433
434

    /*!
    @brief a type for a string

    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
    > A string is a sequence of zero or more Unicode characters.

Niels's avatar
Niels committed
435
    To store objects in C++, a type is defined by the template parameter
Niels's avatar
Niels committed
436
437
    described below. Unicode values are split by the JSON class into
    byte-sized characters during deserialization.
Niels's avatar
Niels committed
438

Niels's avatar
Niels committed
439
440
    @tparam StringType  the container to store strings (e.g., `std::string`).
    Note this container is used for keys/names in objects, see @ref object_t.
Niels's avatar
Niels committed
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

    #### Default type

    With the default values for @a StringType (`std::string`), the default
    value for @a string_t is:

    @code {.cpp}
    std::string
    @endcode

    #### String comparison

    [RFC 7159](http://rfc7159.net/rfc7159) states:
    > Software implementations are typically required to test names of object
    > members for equality. Implementations that transform the textual
    > representation into sequences of Unicode code units and then perform the
    > comparison numerically, code unit by code unit, are interoperable in the
    > sense that implementations will agree in all cases on equality or
    > inequality of two strings. For example, implementations that compare
    > strings with escaped characters unconverted may incorrectly find that
    > `"a\\b"` and `"a\u005Cb"` are not equal.

    This implementation is interoperable as it does compare strings code unit
    by code unit.

    #### Storage

468
469
    String values are stored as pointers in a @ref basic_json type. That is,
    for any access to string values, a pointer of type `string_t*` must be
Niels's avatar
Niels committed
470
    dereferenced.
471

Niels's avatar
Niels committed
472
    @since version 1.0.0
Niels's avatar
Niels committed
473
    */
Niels's avatar
cleanup  
Niels committed
474
    using string_t = StringType;
Niels's avatar
Niels committed
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

    /*!
    @brief a type for a boolean

    [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
    type which differentiates the two literals `true` and `false`.

    To store objects in C++, a type is defined by the template parameter @a
    BooleanType which chooses the type to use.

    #### Default type

    With the default values for @a BooleanType (`bool`), the default value for
    @a boolean_t is:

    @code {.cpp}
    bool
    @endcode

    #### Storage

496
497
    Boolean values are stored directly inside a @ref basic_json type.

Niels's avatar
Niels committed
498
    @since version 1.0.0
Niels's avatar
Niels committed
499
    */
Niels's avatar
cleanup  
Niels committed
500
    using boolean_t = BooleanType;
Niels's avatar
Niels committed
501
502
503
504
505

    /*!
    @brief a type for a number (integer)

    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
Niels's avatar
Niels committed
506
507
508
509
510
511
512
513
514
515
516
517
518
    > The representation of numbers is similar to that used in most
    > programming languages. A number is represented in base 10 using decimal
    > digits. It contains an integer component that may be prefixed with an
    > optional minus sign, which may be followed by a fraction part and/or an
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
    > cannot be represented in the grammar below (such as Infinity and NaN)
    > are not permitted.

    This description includes both integer and floating-point numbers.
    However, C++ allows more precise storage if it is known whether the number
    is a signed integer, an unsigned integer or a floating-point number.
    Therefore, three different types, @ref number_integer_t, @ref
    number_unsigned_t and @ref number_float_t are used.
Niels's avatar
Niels committed
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

    To store integer numbers in C++, a type is defined by the template
    parameter @a NumberIntegerType which chooses the type to use.

    #### Default type

    With the default values for @a NumberIntegerType (`int64_t`), the default
    value for @a number_integer_t is:

    @code {.cpp}
    int64_t
    @endcode

    #### Default behavior

    - The restrictions about leading zeros is not enforced in C++. Instead,
      leading zeros in integer literals lead to an interpretation as octal
      number. Internally, the value will be stored as decimal number. For
Niels's avatar
Niels committed
537
538
      instance, the C++ integer literal `010` will be serialized to `8`.
      During deserialization, leading zeros yield an error.
Niels's avatar
Niels committed
539
540
541
542
543
544
545
546
547
548
    - Not-a-number (NaN) values will be serialized to `null`.

    #### Limits

    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
    > An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be
    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
Niels's avatar
Niels committed
549
550
551
552
    that are out of range will yield over/underflow when used in a
    constructor. During deserialization, too large or small integer numbers
    will be automatically be stored as @ref number_unsigned_t or @ref
    number_float_t.
Niels's avatar
Niels committed
553
554
555
556
557
558
559
560
561
562
563

    [RFC 7159](http://rfc7159.net/rfc7159) further states:
    > Note that when such software is used, numbers that are integers and are
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
    > that implementations will agree exactly on their numeric values.

    As this range is a subrange of the exactly supported range [INT64_MIN,
    INT64_MAX], this class's integer type is interoperable.

    #### Storage

564
565
566
567
    Integer number values are stored directly inside a @ref basic_json type.

    @sa @ref number_float_t -- type for number values (floating-point)

568
569
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)

Niels's avatar
Niels committed
570
    @since version 1.0.0
Niels's avatar
Niels committed
571
    */
Niels's avatar
cleanup  
Niels committed
572
    using number_integer_t = NumberIntegerType;
Niels's avatar
Niels committed
573

574
575
576
577
    /*!
    @brief a type for a number (unsigned)

    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
Niels's avatar
Niels committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
    > The representation of numbers is similar to that used in most
    > programming languages. A number is represented in base 10 using decimal
    > digits. It contains an integer component that may be prefixed with an
    > optional minus sign, which may be followed by a fraction part and/or an
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
    > cannot be represented in the grammar below (such as Infinity and NaN)
    > are not permitted.

    This description includes both integer and floating-point numbers.
    However, C++ allows more precise storage if it is known whether the number
    is a signed integer, an unsigned integer or a floating-point number.
    Therefore, three different types, @ref number_integer_t, @ref
    number_unsigned_t and @ref number_float_t are used.

    To store unsigned integer numbers in C++, a type is defined by the
    template parameter @a NumberUnsignedType which chooses the type to use.
594
595
596

    #### Default type

Niels's avatar
Niels committed
597
598
    With the default values for @a NumberUnsignedType (`uint64_t`), the
    default value for @a number_unsigned_t is:
599
600
601
602
603
604
605
606
607
608

    @code {.cpp}
    uint64_t
    @endcode

    #### Default behavior

    - The restrictions about leading zeros is not enforced in C++. Instead,
      leading zeros in integer literals lead to an interpretation as octal
      number. Internally, the value will be stored as decimal number. For
Niels's avatar
Niels committed
609
610
      instance, the C++ integer literal `010` will be serialized to `8`.
      During deserialization, leading zeros yield an error.
611
612
613
614
615
616
617
618
    - Not-a-number (NaN) values will be serialized to `null`.

    #### Limits

    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
    > An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be
Niels's avatar
Niels committed
619
620
621
622
623
    stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
    number that can be stored is `0`. Integer numbers that are out of range
    will yield over/underflow when used in a constructor. During
    deserialization, too large or small integer numbers will be automatically
    be stored as @ref number_integer_t or @ref number_float_t.
624
625
626
627
628
629
630

    [RFC 7159](http://rfc7159.net/rfc7159) further states:
    > Note that when such software is used, numbers that are integers and are
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
    > that implementations will agree exactly on their numeric values.

    As this range is a subrange (when considered in conjunction with the
Niels's avatar
Niels committed
631
632
    number_integer_t type) of the exactly supported range [0, UINT64_MAX],
    this class's integer type is interoperable.
633
634
635
636
637
638
639
640
641
642
643

    #### Storage

    Integer number values are stored directly inside a @ref basic_json type.

    @sa @ref number_float_t -- type for number values (floating-point)
    @sa @ref number_integer_t -- type for number values (integer)

    @since version 2.0.0
    */
    using number_unsigned_t = NumberUnsignedType;
Niels's avatar
Niels committed
644

Niels's avatar
Niels committed
645
646
647
648
    /*!
    @brief a type for a number (floating-point)

    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
Niels's avatar
Niels committed
649
650
651
652
653
654
655
656
657
658
659
660
661
    > The representation of numbers is similar to that used in most
    > programming languages. A number is represented in base 10 using decimal
    > digits. It contains an integer component that may be prefixed with an
    > optional minus sign, which may be followed by a fraction part and/or an
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
    > cannot be represented in the grammar below (such as Infinity and NaN)
    > are not permitted.

    This description includes both integer and floating-point numbers.
    However, C++ allows more precise storage if it is known whether the number
    is a signed integer, an unsigned integer or a floating-point number.
    Therefore, three different types, @ref number_integer_t, @ref
    number_unsigned_t and @ref number_float_t are used.
Niels's avatar
Niels committed
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677

    To store floating-point numbers in C++, a type is defined by the template
    parameter @a NumberFloatType which chooses the type to use.

    #### Default type

    With the default values for @a NumberFloatType (`double`), the default
    value for @a number_float_t is:

    @code {.cpp}
    double
    @endcode

    #### Default behavior

    - The restrictions about leading zeros is not enforced in C++. Instead,
Niels's avatar
Niels committed
678
679
      leading zeros in floating-point literals will be ignored. Internally,
      the value will be stored as decimal number. For instance, the C++
Niels's avatar
Niels committed
680
681
682
683
684
685
686
687
688
689
      floating-point literal `01.2` will be serialized to `1.2`. During
      deserialization, leading zeros yield an error.
    - Not-a-number (NaN) values will be serialized to `null`.

    #### Limits

    [RFC 7159](http://rfc7159.net/rfc7159) states:
    > This specification allows implementations to set limits on the range and
    > precision of numbers accepted. Since software that implements IEEE
    > 754-2008 binary64 (double precision) numbers is generally available and
Niels's avatar
Niels committed
690
691
692
    > widely used, good interoperability can be achieved by implementations
    > that expect no more precision or range than these provide, in the sense
    > that implementations will approximate JSON numbers within the expected
Niels's avatar
Niels committed
693
694
695
696
    > precision.

    This implementation does exactly follow this approach, as it uses double
    precision floating-point numbers. Note values smaller than
Niels's avatar
Niels committed
697
    `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
Niels's avatar
Niels committed
698
699
700
701
    will be stored as NaN internally and be serialized to `null`.

    #### Storage

702
703
704
705
706
    Floating-point number values are stored directly inside a @ref basic_json
    type.

    @sa @ref number_integer_t -- type for number values (integer)

707
708
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)

Niels's avatar
Niels committed
709
    @since version 1.0.0
Niels's avatar
Niels committed
710
    */
Niels's avatar
cleanup  
Niels committed
711
712
    using number_float_t = NumberFloatType;

Niels's avatar
Niels committed
713
714
    /// @}

Niels's avatar
cleanup  
Niels committed
715

Niels's avatar
Niels committed
716
717
718
    ///////////////////////////
    // JSON type enumeration //
    ///////////////////////////
Niels's avatar
Niels committed
719

Niels's avatar
Niels committed
720
    /*!
Niels's avatar
Niels committed
721
    @brief the JSON type enumeration
Niels's avatar
Niels committed
722

Niels's avatar
Niels committed
723
    This enumeration collects the different JSON types. It is internally used
724
725
    to distinguish the stored values, and the functions @ref is_null(), @ref
    is_object(), @ref is_array(), @ref is_string(), @ref is_boolean(), @ref
Niels's avatar
Niels committed
726
727
728
729
730
731
732
733
734
735
736
737
738
    is_number() (with @ref is_number_integer(), @ref is_number_unsigned(), and
    @ref is_number_float()), @ref is_discarded(), @ref is_primitive(), and
    @ref is_structured() rely on it.

    @note There are three enumeration entries (number_integer,
    number_unsigned, and number_float), because the library distinguishes
    these three types for numbers: @ref number_unsigned_t is used for unsigned
    integers, @ref number_integer_t is used for signed integers, and @ref
    number_float_t is used for floating-point numbers or to approximate
    integers which do not fit in the limits of their respective type.

    @sa @ref basic_json(const value_t value_type) -- create a JSON value with
    the default value for a given type
739

Niels's avatar
Niels committed
740
    @since version 1.0.0
Niels's avatar
Niels committed
741
    */
Niels's avatar
Niels committed
742
743
    enum class value_t : uint8_t
    {
Niels's avatar
Niels committed
744
745
746
747
748
        null,            ///< null value
        object,          ///< object (unordered set of name/value pairs)
        array,           ///< array (ordered collection of values)
        string,          ///< string value
        boolean,         ///< boolean value
Niels's avatar
Niels committed
749
        number_integer,  ///< number value (signed integer)
Niels's avatar
Niels committed
750
751
752
        number_unsigned, ///< number value (unsigned integer)
        number_float,    ///< number value (floating-point)
        discarded        ///< discarded by the the parser callback function
Niels's avatar
Niels committed
753
754
    };

Niels's avatar
Niels committed
755

Niels's avatar
Niels committed
756
  private:
Niels's avatar
Niels committed
757

758
759
    /// helper for exception-safe object creation
    template<typename T, typename... Args>
Niels's avatar
Cleanup    
Niels committed
760
    static T* create(Args&& ... args)
761
762
    {
        AllocatorType<T> alloc;
Niels's avatar
cleanup    
Niels committed
763
        auto deleter = [&](T * object)
Niels's avatar
Cleanup    
Niels committed
764
765
766
        {
            alloc.deallocate(object, 1);
        };
767
768
        std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
        alloc.construct(object.get(), std::forward<Args>(args)...);
Niels's avatar
Niels committed
769
        assert(object.get() != nullptr);
770
771
772
        return object.release();
    }

Niels's avatar
cleanup  
Niels committed
773
774
775
776
    ////////////////////////
    // JSON value storage //
    ////////////////////////

777
778
779
    /*!
    @brief a JSON value

Niels's avatar
Niels committed
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
    The actual storage for a JSON value of the @ref basic_json class. This
    union combines the different storage types for the JSON value types
    defined in @ref value_t.

    JSON type | value_t type    | used type
    --------- | --------------- | ------------------------
    object    | object          | pointer to @ref object_t
    array     | array           | pointer to @ref array_t
    string    | string          | pointer to @ref string_t
    boolean   | boolean         | @ref boolean_t
    number    | number_integer  | @ref number_integer_t
    number    | number_unsigned | @ref number_unsigned_t
    number    | number_float    | @ref number_float_t
    null      | null            | *no value is stored*

    @note Variable-length types (objects, arrays, and strings) are stored as
    pointers. The size of the union should not exceed 64 bits if the default
    value types are used.
798

Niels's avatar
Niels committed
799
    @since version 1.0.0
800
    */
Niels's avatar
cleanup  
Niels committed
801
802
803
804
805
806
807
808
    union json_value
    {
        /// object (stored with pointer to save storage)
        object_t* object;
        /// array (stored with pointer to save storage)
        array_t* array;
        /// string (stored with pointer to save storage)
        string_t* string;
Niels's avatar
Niels committed
809
        /// boolean
Niels's avatar
cleanup  
Niels committed
810
811
812
        boolean_t boolean;
        /// number (integer)
        number_integer_t number_integer;
813
814
        /// number (unsigned integer)
        number_unsigned_t number_unsigned;
Niels's avatar
Niels committed
815
        /// number (floating-point)
Niels's avatar
cleanup  
Niels committed
816
817
818
        number_float_t number_float;

        /// default constructor (for null values)
Niels's avatar
Niels committed
819
        json_value() = default;
Niels's avatar
cleanup  
Niels committed
820
        /// constructor for booleans
821
        json_value(boolean_t v) noexcept : boolean(v) {}
Niels's avatar
cleanup  
Niels committed
822
        /// constructor for numbers (integer)
823
        json_value(number_integer_t v) noexcept : number_integer(v) {}
824
825
        /// constructor for numbers (unsigned)
        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
Niels's avatar
Niels committed
826
        /// constructor for numbers (floating-point)
827
        json_value(number_float_t v) noexcept : number_float(v) {}
Niels's avatar
Niels committed
828
        /// constructor for empty values of a given type
829
        json_value(value_t t)
Niels's avatar
Niels committed
830
831
832
        {
            switch (t)
            {
833
                case value_t::object:
Niels's avatar
Niels committed
834
                {
835
                    object = create<object_t>();
Niels's avatar
Niels committed
836
837
                    break;
                }
Niels's avatar
cleanup  
Niels committed
838

839
                case value_t::array:
Niels's avatar
Niels committed
840
                {
841
                    array = create<array_t>();
Niels's avatar
Niels committed
842
843
                    break;
                }
Niels's avatar
cleanup  
Niels committed
844

845
                case value_t::string:
Niels's avatar
Niels committed
846
                {
847
                    string = create<string_t>("");
Niels's avatar
Niels committed
848
849
                    break;
                }
Niels's avatar
cleanup  
Niels committed
850

851
                case value_t::boolean:
Niels's avatar
Niels committed
852
853
854
855
856
                {
                    boolean = boolean_t(false);
                    break;
                }

857
                case value_t::number_integer:
Niels's avatar
Niels committed
858
859
860
861
                {
                    number_integer = number_integer_t(0);
                    break;
                }
Niels's avatar
Niels committed
862

863
864
865
866
867
                case value_t::number_unsigned:
                {
                    number_unsigned = number_unsigned_t(0);
                    break;
                }
Niels's avatar
Niels committed
868

869
                case value_t::number_float:
Niels's avatar
Niels committed
870
871
872
873
                {
                    number_float = number_float_t(0.0);
                    break;
                }
874
875
876
877
878

                default:
                {
                    break;
                }
Niels's avatar
Niels committed
879
880
            }
        }
Niels's avatar
Niels committed
881
882

        /// constructor for strings
883
        json_value(const string_t& value)
Niels's avatar
Niels committed
884
        {
885
            string = create<string_t>(value);
Niels's avatar
Niels committed
886
887
888
        }

        /// constructor for objects
889
        json_value(const object_t& value)
Niels's avatar
Niels committed
890
        {
891
            object = create<object_t>(value);
Niels's avatar
Niels committed
892
893
894
        }

        /// constructor for arrays
895
        json_value(const array_t& value)
Niels's avatar
Niels committed
896
        {
897
            array = create<array_t>(value);
Niels's avatar
Niels committed
898
        }
Niels's avatar
cleanup  
Niels committed
899
900
    };

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
    /*!
    @brief checks the class invariants

    This function asserts the class invariants. It needs to be called at the
    end of every constructor to make sure that created objects respect the
    invariant. Furthermore, it has to be called each time the type of a JSON
    value is changed, because the invariant expresses a relationship between
    @a m_type and @a m_value.
    */
    void assert_invariant() const
    {
        assert(m_type != value_t::object or m_value.object != nullptr);
        assert(m_type != value_t::array or m_value.array != nullptr);
        assert(m_type != value_t::string or m_value.string != nullptr);
    }
Niels's avatar
Niels committed
916
917

  public:
Niels's avatar
Niels committed
918
919
920
921
    //////////////////////////
    // JSON parser callback //
    //////////////////////////

Niels's avatar
Niels committed
922
923
924
925
926
    /*!
    @brief JSON callback events

    This enumeration lists the parser events that can trigger calling a
    callback function of type @ref parser_callback_t during parsing.
927

Niels's avatar
Niels committed
928
929
    @image html callback_events.png "Example when certain parse events are triggered"

Niels's avatar
Niels committed
930
    @since version 1.0.0
Niels's avatar
Niels committed
931
    */
Niels's avatar
Niels committed
932
933
    enum class parse_event_t : uint8_t
    {
Niels's avatar
Niels committed
934
935
936
937
938
939
940
941
942
943
944
945
        /// the parser read `{` and started to process a JSON object
        object_start,
        /// the parser read `}` and finished processing a JSON object
        object_end,
        /// the parser read `[` and started to process a JSON array
        array_start,
        /// the parser read `]` and finished processing a JSON array
        array_end,
        /// the parser read a key of a value in an object
        key,
        /// the parser finished reading a JSON value
        value
Niels's avatar
Niels committed
946
947
    };

Niels's avatar
Niels committed
948
949
950
951
    /*!
    @brief per-element parser callback type

    With a parser callback function, the result of parsing a JSON text can be
Niels's avatar
Niels committed
952
953
954
955
956
957
958
    influenced. When passed to @ref parse(std::istream&, const
    parser_callback_t) or @ref parse(const string_t&, const parser_callback_t),
    it is called on certain events (passed as @ref parse_event_t via parameter
    @a event) with a set recursion depth @a depth and context JSON value
    @a parsed. The return value of the callback function is a boolean
    indicating whether the element that emitted the callback shall be kept or
    not.
Niels's avatar
Niels committed
959
960
961
962
963
964
965
966
967
968
969
970
971
972

    We distinguish six scenarios (determined by the event type) in which the
    callback function can be called. The following table describes the values
    of the parameters @a depth, @a event, and @a parsed.

    parameter @a event | description | parameter @a depth | parameter @a parsed
    ------------------ | ----------- | ------------------ | -------------------
    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
    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
    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
    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
    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
    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value

Niels's avatar
Niels committed
973
974
    @image html callback_events.png "Example when certain parse events are triggered"

Niels's avatar
Niels committed
975
976
    Discarding a value (i.e., returning `false`) has different effects
    depending on the context in which function was called:
Niels's avatar
Niels committed
977
978
979

    - Discarded values in structured types are skipped. That is, the parser
      will behave as if the discarded value was never read.
Niels's avatar
Niels committed
980
981
    - In case a value outside a structured type is skipped, it is replaced
      with `null`. This case happens if the top-level element is skipped.
Niels's avatar
Niels committed
982

Niels's avatar
Niels committed
983
    @param[in] depth  the depth of the recursion during parsing
Niels's avatar
Niels committed
984

Niels's avatar
Niels committed
985
    @param[in] event  an event of type parse_event_t indicating the context in
Niels's avatar
Niels committed
986
987
988
989
990
991
992
993
994
995
996
    the callback function has been called

    @param[in,out] parsed  the current intermediate parse result; note that
    writing to this value has no effect for parse_event_t::key events

    @return Whether the JSON value which called the function during parsing
    should be kept (`true`) or not (`false`). In the latter case, it is either
    skipped completely or replaced by an empty discarded object.

    @sa @ref parse(std::istream&, parser_callback_t) or
    @ref parse(const string_t&, parser_callback_t) for examples
997

Niels's avatar
Niels committed
998
    @since version 1.0.0
Niels's avatar
Niels committed
999
    */
Niels's avatar
Niels committed
1000
    using parser_callback_t = std::function<bool(int depth,
For faster browsing, not all history is shown. View entire blame