1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
3  
// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/json
8  
// Official repository: https://github.com/boostorg/json
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_JSON_VALUE_HPP
11  
#ifndef BOOST_JSON_VALUE_HPP
12  
#define BOOST_JSON_VALUE_HPP
12  
#define BOOST_JSON_VALUE_HPP
13  

13  

14  
#include <boost/core/detail/static_assert.hpp>
14  
#include <boost/core/detail/static_assert.hpp>
15  
#include <boost/json/detail/config.hpp>
15  
#include <boost/json/detail/config.hpp>
16  
#include <boost/json/array.hpp>
16  
#include <boost/json/array.hpp>
17  
#include <boost/json/kind.hpp>
17  
#include <boost/json/kind.hpp>
18  
#include <boost/json/object.hpp>
18  
#include <boost/json/object.hpp>
19  
#include <boost/json/pilfer.hpp>
19  
#include <boost/json/pilfer.hpp>
20  
#include <boost/json/set_pointer_options.hpp>
20  
#include <boost/json/set_pointer_options.hpp>
21  
#include <boost/json/storage_ptr.hpp>
21  
#include <boost/json/storage_ptr.hpp>
22  
#include <boost/json/string.hpp>
22  
#include <boost/json/string.hpp>
23  
#include <boost/json/string_view.hpp>
23  
#include <boost/json/string_view.hpp>
24  
#include <boost/json/value_ref.hpp>
24  
#include <boost/json/value_ref.hpp>
25  
#include <boost/json/detail/except.hpp>
25  
#include <boost/json/detail/except.hpp>
26  
#include <boost/json/detail/value.hpp>
26  
#include <boost/json/detail/value.hpp>
27  
#include <cstdlib>
27  
#include <cstdlib>
28  
#include <cstring>
28  
#include <cstring>
29  
#include <initializer_list>
29  
#include <initializer_list>
30  
#include <iosfwd>
30  
#include <iosfwd>
31  
#include <limits>
31  
#include <limits>
32  
#include <new>
32  
#include <new>
33  
#include <type_traits>
33  
#include <type_traits>
34  
#include <utility>
34  
#include <utility>
35  

35  

36  
namespace boost {
36  
namespace boost {
37  
namespace json {
37  
namespace json {
38  

38  

39  
//----------------------------------------------------------
39  
//----------------------------------------------------------
40  

40  

41  
/** The type used to represent any JSON value
41  
/** The type used to represent any JSON value
42  

42  

43  
    This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular)
43  
    This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular)
44  
    type which works like a variant of the basic JSON data types: array,
44  
    type which works like a variant of the basic JSON data types: array,
45  
    object, string, number, boolean, and null.
45  
    object, string, number, boolean, and null.
46  

46  

47  
    @par Thread Safety
47  
    @par Thread Safety
48  
    Distinct instances may be accessed concurrently. Non-const member
48  
    Distinct instances may be accessed concurrently. Non-const member
49  
    functions of a shared instance may not be called concurrently with any
49  
    functions of a shared instance may not be called concurrently with any
50  
    other member functions of that instance.
50  
    other member functions of that instance.
51  
*/
51  
*/
52  
class value
52  
class value
53  
{
53  
{
54  
#ifndef BOOST_JSON_DOCS
54  
#ifndef BOOST_JSON_DOCS
55  
    using scalar = detail::scalar;
55  
    using scalar = detail::scalar;
56  

56  

57  
    union
57  
    union
58  
    {
58  
    {
59  
        storage_ptr sp_; // must come first
59  
        storage_ptr sp_; // must come first
60  
        array       arr_;
60  
        array       arr_;
61  
        object      obj_;
61  
        object      obj_;
62  
        string      str_;
62  
        string      str_;
63  
        scalar      sca_;
63  
        scalar      sca_;
64  
    };
64  
    };
65  
#endif
65  
#endif
66  

66  

67  
    struct init_iter;
67  
    struct init_iter;
68  

68  

69  
#ifndef BOOST_JSON_DOCS
69  
#ifndef BOOST_JSON_DOCS
70  
    // VFALCO doc toolchain incorrectly treats this as public
70  
    // VFALCO doc toolchain incorrectly treats this as public
71  
    friend struct detail::access;
71  
    friend struct detail::access;
72  
#endif
72  
#endif
73  

73  

74  
    explicit
74  
    explicit
75  
    value(
75  
    value(
76  
        detail::unchecked_array&& ua)
76  
        detail::unchecked_array&& ua)
77  
        : arr_(std::move(ua))
77  
        : arr_(std::move(ua))
78  
    {
78  
    {
79  
    }
79  
    }
80  

80  

81  
    explicit
81  
    explicit
82  
    value(
82  
    value(
83  
        detail::unchecked_object&& uo)
83  
        detail::unchecked_object&& uo)
84  
        : obj_(std::move(uo))
84  
        : obj_(std::move(uo))
85  
    {
85  
    {
86  
    }
86  
    }
87  

87  

88  
    value(
88  
    value(
89  
        detail::key_t const&,
89  
        detail::key_t const&,
90  
        string_view s,
90  
        string_view s,
91  
        storage_ptr sp)
91  
        storage_ptr sp)
92  
        : str_(detail::key_t{}, s, std::move(sp))
92  
        : str_(detail::key_t{}, s, std::move(sp))
93  
    {
93  
    {
94  
    }
94  
    }
95  

95  

96  
    value(
96  
    value(
97  
        detail::key_t const&,
97  
        detail::key_t const&,
98  
        string_view s1,
98  
        string_view s1,
99  
        string_view s2,
99  
        string_view s2,
100  
        storage_ptr sp)
100  
        storage_ptr sp)
101  
        : str_(detail::key_t{}, s1, s2, std::move(sp))
101  
        : str_(detail::key_t{}, s1, s2, std::move(sp))
102  
    {
102  
    {
103  
    }
103  
    }
104  

104  

105  
    inline bool is_scalar() const noexcept
105  
    inline bool is_scalar() const noexcept
106  
    {
106  
    {
107  
        return sca_.k < json::kind::string;
107  
        return sca_.k < json::kind::string;
108  
    }
108  
    }
109  

109  

110  
public:
110  
public:
111  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
111  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
112  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
112  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
113  

113  

114  
    /** Destructor.
114  
    /** Destructor.
115  

115  

116  
        The value and all of its contents are destroyed. Any dynamically
116  
        The value and all of its contents are destroyed. Any dynamically
117  
        allocated memory that was allocated internally is freed.
117  
        allocated memory that was allocated internally is freed.
118  

118  

119  
        @par Complexity
119  
        @par Complexity
120  
        Constant, or linear in size for array or object.
120  
        Constant, or linear in size for array or object.
121  

121  

122  
        @par Exception Safety
122  
        @par Exception Safety
123  
        No-throw guarantee.
123  
        No-throw guarantee.
124  
    */
124  
    */
125  
    BOOST_JSON_DECL
125  
    BOOST_JSON_DECL
126  
    ~value() noexcept;
126  
    ~value() noexcept;
127  

127  

128  
    /** Constructors.
128  
    /** Constructors.
129  

129  

130  
        Construct a new `value`.
130  
        Construct a new `value`.
131  

131  

132  
        @li **(1)**--**(3)** the constructed value is null.
132  
        @li **(1)**--**(3)** the constructed value is null.
133  
        @li **(4)** the constructed value contains a copy of `b`.
133  
        @li **(4)** the constructed value contains a copy of `b`.
134  
        @li **(5)**--**(9)** the constructed value contains a copy of `i`.
134  
        @li **(5)**--**(9)** the constructed value contains a copy of `i`.
135  
        @li **(10)**--**(14)** the constructed value contains a copy of `u`.
135  
        @li **(10)**--**(14)** the constructed value contains a copy of `u`.
136  
        @li **(15)** the constructed value contains a copy of `d`.
136  
        @li **(15)** the constructed value contains a copy of `d`.
137  
        @li **(16)**, **(19)** the constructed value contains a copy of the
137  
        @li **(16)**, **(19)** the constructed value contains a copy of the
138  
            string `s`.
138  
            string `s`.
139  
        @li **(17)** the constructed value contains a copy of the
139  
        @li **(17)** the constructed value contains a copy of the
140  
            null-terminated string `s`.
140  
            null-terminated string `s`.
141  
        @li **(18)** the constructed value takes ownership of `s`'s storage.
141  
        @li **(18)** the constructed value takes ownership of `s`'s storage.
142  
        @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise
142  
        @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise
143  
            equivalent to **(19)**.
143  
            equivalent to **(19)**.
144  
        @li **(21)** the constructed value contains an empty string.
144  
        @li **(21)** the constructed value contains an empty string.
145  
        @li **(22)** the constructed value takes ownership of `arr`'s storage.
145  
        @li **(22)** the constructed value takes ownership of `arr`'s storage.
146  
        @li **(23)** the constructed value contains an element-wise copy of the
146  
        @li **(23)** the constructed value contains an element-wise copy of the
147  
            array `arr`.
147  
            array `arr`.
148  
        @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**,
148  
        @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**,
149  
            otherwise equivalent to **(23)**.
149  
            otherwise equivalent to **(23)**.
150  
        @li **(25)** the constructed value contains an empty array.
150  
        @li **(25)** the constructed value contains an empty array.
151  
        @li **(26)** the constructed value takes ownership of `obj`'s storage.
151  
        @li **(26)** the constructed value takes ownership of `obj`'s storage.
152  
        @li **(27)** the constructed value contains an element-wise copy of the
152  
        @li **(27)** the constructed value contains an element-wise copy of the
153  
            object `obj`.
153  
            object `obj`.
154  
        @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**,
154  
        @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**,
155  
            otherwise equivalent to **(27)**.
155  
            otherwise equivalent to **(27)**.
156  
        @li **(29)** the constructed value contains an empty object.
156  
        @li **(29)** the constructed value contains an empty object.
157  
        @li **(30)** the constructed value's contents are formed by
157  
        @li **(30)** the constructed value's contents are formed by
158  
            constructing from `init` and `sp` (see \<\<initializer_lists\>\>).
158  
            constructing from `init` and `sp` (see \<\<initializer_lists\>\>).
159  
        @li **(31)**, **(32)** the constructed value contains a copy of the
159  
        @li **(31)**, **(32)** the constructed value contains a copy of the
160  
            contents of `other`.
160  
            contents of `other`.
161  
        @li **(33)** the constructed value acquires ownership of the contents
161  
        @li **(33)** the constructed value acquires ownership of the contents
162  
            of `other`.
162  
            of `other`.
163  
        @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`;
163  
        @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`;
164  
            otherwise equivalent to **(32)**.
164  
            otherwise equivalent to **(32)**.
165  
        @li **(35)** the constructed value acquires ownership of the contents
165  
        @li **(35)** the constructed value acquires ownership of the contents
166  
            of `other` using pilfer semantics. This is more efficient than move
166  
            of `other` using pilfer semantics. This is more efficient than move
167  
            construction, when it is known that the moved-from object will be
167  
            construction, when it is known that the moved-from object will be
168  
            immediately destroyed afterwards.
168  
            immediately destroyed afterwards.
169  

169  

170  
        With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**,
170  
        With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**,
171  
        {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value
171  
        {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value
172  
        uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**,
172  
        uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**,
173  
        {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of
173  
        {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of
174  
        the argument (`s`, `arr`, obj`, or `value`). In either case the value
174  
        the argument (`s`, `arr`, obj`, or `value`). In either case the value
175  
        will share the ownership of the memory resource. With **(1)**
175  
        will share the ownership of the memory resource. With **(1)**
176  
        it uses the \<\<default_memory_resource, default memory resource\>\>.
176  
        it uses the \<\<default_memory_resource, default memory resource\>\>.
177  

177  

178  
        After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves
178  
        After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves
179  
        as if newly constructed with its current storage pointer (i.e. becomes
179  
        as if newly constructed with its current storage pointer (i.e. becomes
180  
        an empty string, array, object, or null value).
180  
        an empty string, array, object, or null value).
181  

181  

182  
        After **(35)** `other` is not in a usable state and may only be
182  
        After **(35)** `other` is not in a usable state and may only be
183  
        destroyed.
183  
        destroyed.
184  

184  

185  
        @par Complexity
185  
        @par Complexity
186  
        @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
186  
        @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
187  
            {sp} **(26)**, **(29)**, **(33)**, **(35)** constant.
187  
            {sp} **(26)**, **(29)**, **(33)**, **(35)** constant.
188  
        @li **(16)**, **(19)** linear in `s.size()`.
188  
        @li **(16)**, **(19)** linear in `s.size()`.
189  
        @li **(17)** linear in `std::strlen(s)`.
189  
        @li **(17)** linear in `std::strlen(s)`.
190  
        @li **(20)** if `*s.storage() == *sp` constant, otherwise linear
190  
        @li **(20)** if `*s.storage() == *sp` constant, otherwise linear
191  
            in `s.size()`.
191  
            in `s.size()`.
192  
        @li **(23)** linear in `arr.size()`.
192  
        @li **(23)** linear in `arr.size()`.
193  
        @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear
193  
        @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear
194  
            in `arr.size()`.
194  
            in `arr.size()`.
195  
        @li **(27)** linear in `obj.size()`.
195  
        @li **(27)** linear in `obj.size()`.
196  
        @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear
196  
        @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear
197  
            in `obj.size()`.
197  
            in `obj.size()`.
198  
        @li **(30)** linear in `init.size()`.
198  
        @li **(30)** linear in `init.size()`.
199  
        @li **(31)**, **(32)** linear in the size of `other`.
199  
        @li **(31)**, **(32)** linear in the size of `other`.
200  
        @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in
200  
        @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in
201  
            the size of `other`.
201  
            the size of `other`.
202  

202  

203  
        The size of `other` is either the size of the underlying container
203  
        The size of `other` is either the size of the underlying container
204  
        (if there is one), or can be considered to be 1.
204  
        (if there is one), or can be considered to be 1.
205  

205  

206  
        @par Exception Safety
206  
        @par Exception Safety
207  
        @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
207  
        @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
208  
            **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee.
208  
            **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee.
209  
        @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**,
209  
        @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**,
210  
            **(30)**--**(32)** strong guarantee.
210  
            **(30)**--**(32)** strong guarantee.
211  
        @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise
211  
        @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise
212  
            strong guarantee.
212  
            strong guarantee.
213  
        @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise
213  
        @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise
214  
            strong guarantee.
214  
            strong guarantee.
215  
        @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise
215  
        @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise
216  
            strong guarantee.
216  
            strong guarantee.
217  
        @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise
217  
        @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise
218  
            strong guarantee.
218  
            strong guarantee.
219  

219  

220  
        Calls to `memory_resource::allocate` may throw.
220  
        Calls to `memory_resource::allocate` may throw.
221  

221  

222  
        @see @ref pilfer,
222  
        @see @ref pilfer,
223  
            [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
223  
            [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
224  
                                                         //
224  
                                                         //
225  
        @{
225  
        @{
226  
    */
226  
    */
227  
    value() noexcept
227  
    value() noexcept
228  
        : sca_()
228  
        : sca_()
229  
    {
229  
    {
230  
    }
230  
    }
231  

231  

232  
    /** Overload
232  
    /** Overload
233  

233  

234  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
234  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
235  
               to use.
235  
               to use.
236  
    */
236  
    */
237  
    explicit
237  
    explicit
238  
    value(storage_ptr sp) noexcept
238  
    value(storage_ptr sp) noexcept
239  
        : sca_(std::move(sp))
239  
        : sca_(std::move(sp))
240  
    {
240  
    {
241  
    }
241  
    }
242  

242  

243  
    /// Overload
243  
    /// Overload
244  
    value(
244  
    value(
245  
        std::nullptr_t,
245  
        std::nullptr_t,
246  
        storage_ptr sp = {}) noexcept
246  
        storage_ptr sp = {}) noexcept
247  
        : sca_(std::move(sp))
247  
        : sca_(std::move(sp))
248  
    {
248  
    {
249  
    }
249  
    }
250  

250  

251  
    /** Overload
251  
    /** Overload
252  

252  

253  
        @param b The boolean to construct with.
253  
        @param b The boolean to construct with.
254  
        @param sp
254  
        @param sp
255  
    */
255  
    */
256  
#ifdef BOOST_JSON_DOCS
256  
#ifdef BOOST_JSON_DOCS
257  
    value(
257  
    value(
258  
        bool b,
258  
        bool b,
259  
        storage_ptr sp = {}) noexcept;
259  
        storage_ptr sp = {}) noexcept;
260  
#else
260  
#else
261  
    template<class T
261  
    template<class T
262  
        ,class = typename std::enable_if<
262  
        ,class = typename std::enable_if<
263  
            std::is_same<T, bool>::value>::type
263  
            std::is_same<T, bool>::value>::type
264  
    >
264  
    >
265  
    value(
265  
    value(
266  
        T b,
266  
        T b,
267  
        storage_ptr sp = {}) noexcept
267  
        storage_ptr sp = {}) noexcept
268  
        : sca_(b, std::move(sp))
268  
        : sca_(b, std::move(sp))
269  
    {
269  
    {
270  
    }
270  
    }
271  
#endif
271  
#endif
272  

272  

273  
    /** Overload
273  
    /** Overload
274  

274  

275  
        @param i The number to construct with.
275  
        @param i The number to construct with.
276  
        @param sp
276  
        @param sp
277  
    */
277  
    */
278  
    value(
278  
    value(
279  
        signed char i,
279  
        signed char i,
280  
        storage_ptr sp = {}) noexcept
280  
        storage_ptr sp = {}) noexcept
281  
        : sca_(static_cast<std::int64_t>(
281  
        : sca_(static_cast<std::int64_t>(
282  
            i), std::move(sp))
282  
            i), std::move(sp))
283  
    {
283  
    {
284  
    }
284  
    }
285  

285  

286  
    /// Overload
286  
    /// Overload
287  
    value(
287  
    value(
288  
        short i,
288  
        short i,
289  
        storage_ptr sp = {}) noexcept
289  
        storage_ptr sp = {}) noexcept
290  
        : sca_(static_cast<std::int64_t>(
290  
        : sca_(static_cast<std::int64_t>(
291  
            i), std::move(sp))
291  
            i), std::move(sp))
292  
    {
292  
    {
293  
    }
293  
    }
294  

294  

295  
    /// Overload
295  
    /// Overload
296  
    value(
296  
    value(
297  
        int i,
297  
        int i,
298  
        storage_ptr sp = {}) noexcept
298  
        storage_ptr sp = {}) noexcept
299  
        : sca_(static_cast<std::int64_t>(i),
299  
        : sca_(static_cast<std::int64_t>(i),
300  
            std::move(sp))
300  
            std::move(sp))
301  
    {
301  
    {
302  
    }
302  
    }
303  

303  

304  
    /// Overload
304  
    /// Overload
305  
    value(
305  
    value(
306  
        long i,
306  
        long i,
307  
        storage_ptr sp = {}) noexcept
307  
        storage_ptr sp = {}) noexcept
308  
        : sca_(static_cast<std::int64_t>(i),
308  
        : sca_(static_cast<std::int64_t>(i),
309  
            std::move(sp))
309  
            std::move(sp))
310  
    {
310  
    {
311  
    }
311  
    }
312  

312  

313  
    /// Overload
313  
    /// Overload
314  
    value(
314  
    value(
315  
        long long i,
315  
        long long i,
316  
        storage_ptr sp = {}) noexcept
316  
        storage_ptr sp = {}) noexcept
317  
        : sca_(static_cast<std::int64_t>(i),
317  
        : sca_(static_cast<std::int64_t>(i),
318  
            std::move(sp))
318  
            std::move(sp))
319  
    {
319  
    {
320  
    }
320  
    }
321  

321  

322  
    /** Overload
322  
    /** Overload
323  

323  

324  
        @param u The number to construct with.
324  
        @param u The number to construct with.
325  
        @param sp
325  
        @param sp
326  
    */
326  
    */
327  
    value(
327  
    value(
328  
        unsigned char u,
328  
        unsigned char u,
329  
        storage_ptr sp = {}) noexcept
329  
        storage_ptr sp = {}) noexcept
330  
        : sca_(static_cast<std::uint64_t>(
330  
        : sca_(static_cast<std::uint64_t>(
331  
            u), std::move(sp))
331  
            u), std::move(sp))
332  
    {
332  
    {
333  
    }
333  
    }
334  

334  

335  
    /// Overload
335  
    /// Overload
336  
    value(
336  
    value(
337  
        unsigned short u,
337  
        unsigned short u,
338  
        storage_ptr sp = {}) noexcept
338  
        storage_ptr sp = {}) noexcept
339  
        : sca_(static_cast<std::uint64_t>(u),
339  
        : sca_(static_cast<std::uint64_t>(u),
340  
            std::move(sp))
340  
            std::move(sp))
341  
    {
341  
    {
342  
    }
342  
    }
343  

343  

344  
    /// Overload
344  
    /// Overload
345  
    value(
345  
    value(
346  
        unsigned int u,
346  
        unsigned int u,
347  
        storage_ptr sp = {}) noexcept
347  
        storage_ptr sp = {}) noexcept
348  
        : sca_(static_cast<std::uint64_t>(u),
348  
        : sca_(static_cast<std::uint64_t>(u),
349  
            std::move(sp))
349  
            std::move(sp))
350  
    {
350  
    {
351  
    }
351  
    }
352  

352  

353  
    /// Overload
353  
    /// Overload
354  
    value(
354  
    value(
355  
        unsigned long u,
355  
        unsigned long u,
356  
        storage_ptr sp = {}) noexcept
356  
        storage_ptr sp = {}) noexcept
357  
        : sca_(static_cast<std::uint64_t>(u),
357  
        : sca_(static_cast<std::uint64_t>(u),
358  
            std::move(sp))
358  
            std::move(sp))
359  
    {
359  
    {
360  
    }
360  
    }
361  

361  

362  
    /// Overload
362  
    /// Overload
363  
    value(
363  
    value(
364  
        unsigned long long u,
364  
        unsigned long long u,
365  
        storage_ptr sp = {}) noexcept
365  
        storage_ptr sp = {}) noexcept
366  
        : sca_(static_cast<std::uint64_t>(u),
366  
        : sca_(static_cast<std::uint64_t>(u),
367  
            std::move(sp))
367  
            std::move(sp))
368  
    {
368  
    {
369  
    }
369  
    }
370  

370  

371  
    /** Overload
371  
    /** Overload
372  

372  

373  
        @param d The number to construct with.
373  
        @param d The number to construct with.
374  
        @param sp
374  
        @param sp
375  
    */
375  
    */
376  
    value(
376  
    value(
377  
        double d,
377  
        double d,
378  
        storage_ptr sp = {}) noexcept
378  
        storage_ptr sp = {}) noexcept
379  
        : sca_(d, std::move(sp))
379  
        : sca_(d, std::move(sp))
380  
    {
380  
    {
381  
    }
381  
    }
382  

382  

383  
    /** Overload
383  
    /** Overload
384  

384  

385  
        @param s The string to construct with.
385  
        @param s The string to construct with.
386  
        @param sp
386  
        @param sp
387  
    */
387  
    */
388  
    value(
388  
    value(
389  
        string_view s,
389  
        string_view s,
390  
        storage_ptr sp = {})
390  
        storage_ptr sp = {})
391  
        : str_(s, std::move(sp))
391  
        : str_(s, std::move(sp))
392  
    {
392  
    {
393  
    }
393  
    }
394  

394  

395  
    /// Overload
395  
    /// Overload
396  
    value(
396  
    value(
397  
        char const* s,
397  
        char const* s,
398  
        storage_ptr sp = {})
398  
        storage_ptr sp = {})
399  
        : str_(s, std::move(sp))
399  
        : str_(s, std::move(sp))
400  
    {
400  
    {
401  
    }
401  
    }
402  

402  

403  
    /// Overload
403  
    /// Overload
404  
    value(
404  
    value(
405  
        string s) noexcept
405  
        string s) noexcept
406  
        : str_(std::move(s))
406  
        : str_(std::move(s))
407  
    {
407  
    {
408  
    }
408  
    }
409  

409  

410  
    /// Overload
410  
    /// Overload
411  
    value(
411  
    value(
412  
        string const& s,
412  
        string const& s,
413  
        storage_ptr sp)
413  
        storage_ptr sp)
414  
        : str_(
414  
        : str_(
415  
            s,
415  
            s,
416  
            std::move(sp))
416  
            std::move(sp))
417  
    {
417  
    {
418  
    }
418  
    }
419  

419  

420  
    /// Overload
420  
    /// Overload
421  
    value(
421  
    value(
422  
        string&& s,
422  
        string&& s,
423  
        storage_ptr sp)
423  
        storage_ptr sp)
424  
        : str_(
424  
        : str_(
425  
            std::move(s),
425  
            std::move(s),
426  
            std::move(sp))
426  
            std::move(sp))
427  
    {
427  
    {
428  
    }
428  
    }
429  

429  

430  
    /// Overload
430  
    /// Overload
431  
    value(
431  
    value(
432  
        string_kind_t,
432  
        string_kind_t,
433  
        storage_ptr sp = {}) noexcept
433  
        storage_ptr sp = {}) noexcept
434  
        : str_(std::move(sp))
434  
        : str_(std::move(sp))
435  
    {
435  
    {
436  
    }
436  
    }
437  

437  

438  
    /** Overload
438  
    /** Overload
439  

439  

440  
        @param arr The array to construct with.
440  
        @param arr The array to construct with.
441  
    */
441  
    */
442  
    value(array arr) noexcept
442  
    value(array arr) noexcept
443  
        : arr_(std::move(arr))
443  
        : arr_(std::move(arr))
444  
    {
444  
    {
445  
    }
445  
    }
446  

446  

447  
    /// Overload
447  
    /// Overload
448  
    value(
448  
    value(
449  
        array const& arr,
449  
        array const& arr,
450  
        storage_ptr sp)
450  
        storage_ptr sp)
451  
        : arr_(
451  
        : arr_(
452  
            arr,
452  
            arr,
453  
            std::move(sp))
453  
            std::move(sp))
454  
    {
454  
    {
455  
    }
455  
    }
456  

456  

457  
    /// Overload
457  
    /// Overload
458  
    value(
458  
    value(
459  
        array&& arr,
459  
        array&& arr,
460  
        storage_ptr sp)
460  
        storage_ptr sp)
461  
        : arr_(
461  
        : arr_(
462  
            std::move(arr),
462  
            std::move(arr),
463  
            std::move(sp))
463  
            std::move(sp))
464  
    {
464  
    {
465  
    }
465  
    }
466  

466  

467  
    /// Overload
467  
    /// Overload
468  
    value(
468  
    value(
469  
        array_kind_t,
469  
        array_kind_t,
470  
        storage_ptr sp = {}) noexcept
470  
        storage_ptr sp = {}) noexcept
471  
        : arr_(std::move(sp))
471  
        : arr_(std::move(sp))
472  
    {
472  
    {
473  
    }
473  
    }
474  

474  

475  
    /** Overload
475  
    /** Overload
476  

476  

477  
        @param obj The object to construct with.
477  
        @param obj The object to construct with.
478  
    */
478  
    */
479  
    value(object obj) noexcept
479  
    value(object obj) noexcept
480  
        : obj_(std::move(obj))
480  
        : obj_(std::move(obj))
481  
    {
481  
    {
482  
    }
482  
    }
483  

483  

484  
    /// Overload
484  
    /// Overload
485  
    value(
485  
    value(
486  
        object const& obj,
486  
        object const& obj,
487  
        storage_ptr sp)
487  
        storage_ptr sp)
488  
        : obj_( obj, std::move(sp) )
488  
        : obj_( obj, std::move(sp) )
489  
    {
489  
    {
490  
    }
490  
    }
491  

491  

492  
    /// Overload
492  
    /// Overload
493  
    value(
493  
    value(
494  
        object&& obj,
494  
        object&& obj,
495  
        storage_ptr sp)
495  
        storage_ptr sp)
496  
        : obj_( std::move(obj), std::move(sp) )
496  
        : obj_( std::move(obj), std::move(sp) )
497  
    {
497  
    {
498  
    }
498  
    }
499  

499  

500  
    /// Overload
500  
    /// Overload
501  
    value(
501  
    value(
502  
        object_kind_t,
502  
        object_kind_t,
503  
        storage_ptr sp = {}) noexcept
503  
        storage_ptr sp = {}) noexcept
504  
        : obj_(std::move(sp))
504  
        : obj_(std::move(sp))
505  
    {
505  
    {
506  
    }
506  
    }
507  

507  

508  
    /** Overload
508  
    /** Overload
509  

509  

510  
        @param init The initializer list to construct from.
510  
        @param init The initializer list to construct from.
511  
        @param sp
511  
        @param sp
512  
    */
512  
    */
513  
    BOOST_JSON_DECL
513  
    BOOST_JSON_DECL
514  
    value(
514  
    value(
515  
        std::initializer_list<value_ref> init,
515  
        std::initializer_list<value_ref> init,
516  
        storage_ptr sp = {});
516  
        storage_ptr sp = {});
517  

517  

518  
    /** Overload
518  
    /** Overload
519  

519  

520  
        @param other Another `value`.
520  
        @param other Another `value`.
521  
    */
521  
    */
522  
    value(value const& other)
522  
    value(value const& other)
523  
        : value(other, other.storage())
523  
        : value(other, other.storage())
524  
    {
524  
    {
525  
    }
525  
    }
526  

526  

527  
    /// Overload
527  
    /// Overload
528  
    BOOST_JSON_DECL
528  
    BOOST_JSON_DECL
529  
    value(
529  
    value(
530  
        value const& other,
530  
        value const& other,
531  
        storage_ptr sp);
531  
        storage_ptr sp);
532  

532  

533  
    /// Overload
533  
    /// Overload
534  
    BOOST_JSON_DECL
534  
    BOOST_JSON_DECL
535  
    value(value&& other) noexcept;
535  
    value(value&& other) noexcept;
536  

536  

537  
    /// Overload
537  
    /// Overload
538  
    BOOST_JSON_DECL
538  
    BOOST_JSON_DECL
539  
    value(
539  
    value(
540  
        value&& other,
540  
        value&& other,
541  
        storage_ptr sp);
541  
        storage_ptr sp);
542  

542  

543  
    /// Overload
543  
    /// Overload
544  
    value(pilfered<value> other) noexcept
544  
    value(pilfered<value> other) noexcept
545  
    {
545  
    {
546  
        relocate(this, other.get());
546  
        relocate(this, other.get());
547  
        ::new(&other.get().sca_) scalar();
547  
        ::new(&other.get().sca_) scalar();
548  
    }
548  
    }
549  
    /// @}
549  
    /// @}
550  

550  

551  
    //------------------------------------------------------
551  
    //------------------------------------------------------
552  
    //
552  
    //
553  
    // Assignment
553  
    // Assignment
554  
    //
554  
    //
555  
    //------------------------------------------------------
555  
    //------------------------------------------------------
556  

556  

557  
    /** Assignment.
557  
    /** Assignment.
558  

558  

559  
        Replaces the contents of this value.
559  
        Replaces the contents of this value.
560  

560  

561  
        @li **(1)** replaces with an element-wise copy of the contents of
561  
        @li **(1)** replaces with an element-wise copy of the contents of
562  
            `other`.
562  
            `other`.
563  
        @li **(2)** replaces with the contents `other` using move semantics
563  
        @li **(2)** replaces with the contents `other` using move semantics
564  
            (see below).
564  
            (see below).
565  
        @li **(3)** replaces with the value formed by constructing from `init`
565  
        @li **(3)** replaces with the value formed by constructing from `init`
566  
            and `this->storage()` (see \<\<initializer_lists\>\>).
566  
            and `this->storage()` (see \<\<initializer_lists\>\>).
567  
        @li **(4)** replaces with null.
567  
        @li **(4)** replaces with null.
568  
        @li **(5)** replaces with the boolean value `b`.
568  
        @li **(5)** replaces with the boolean value `b`.
569  
        @li **(6)**--**(10)** replaces with the signed integer `i`.
569  
        @li **(6)**--**(10)** replaces with the signed integer `i`.
570  
        @li **(11)**--**(15)** replaces with the unsigned integer `u`.
570  
        @li **(11)**--**(15)** replaces with the unsigned integer `u`.
571  
        @li **(16)** replaces with the number `d`.
571  
        @li **(16)** replaces with the number `d`.
572  
        @li **(17)**, **(19)** replaces with a copy of the string `s`.
572  
        @li **(17)**, **(19)** replaces with a copy of the string `s`.
573  
        @li **(18)**, equivalent to `*this = string_view(s)`.
573  
        @li **(18)**, equivalent to `*this = string_view(s)`.
574  
        @li **(20)** replaces with the string `s` using move semantics
574  
        @li **(20)** replaces with the string `s` using move semantics
575  
            see below.
575  
            see below.
576  
        @li **(21)** replaces with a copy of the array `arr`.
576  
        @li **(21)** replaces with a copy of the array `arr`.
577  
        @li **(22)** replaces with the array `arr` using move semantics
577  
        @li **(22)** replaces with the array `arr` using move semantics
578  
            (see below).
578  
            (see below).
579  
        @li **(23)** replaces with a copy of the object `obj`.
579  
        @li **(23)** replaces with a copy of the object `obj`.
580  
        @li **(24)** replaces with the object `obj` using move semantics
580  
        @li **(24)** replaces with the object `obj` using move semantics
581  
            (see below).
581  
            (see below).
582  

582  

583  
        Move assignment for `value` never changes the associated memory
583  
        Move assignment for `value` never changes the associated memory
584  
        resource. Because of this if the memory resource of the assigned value
584  
        resource. Because of this if the memory resource of the assigned value
585  
        differs from that of `*this`, the operation is equivalent to a copy.
585  
        differs from that of `*this`, the operation is equivalent to a copy.
586  
        Otherwise, it replaces the underlying storage in constant time without
586  
        Otherwise, it replaces the underlying storage in constant time without
587  
        the possibility of exceptions.
587  
        the possibility of exceptions.
588  

588  

589  
        @par Complexity
589  
        @par Complexity
590  
        @li **(1)** linear in the sizes of `*this` and `other`.
590  
        @li **(1)** linear in the sizes of `*this` and `other`.
591  
        @li **(2)** constant if `*this->storage() == *other.storage()`,
591  
        @li **(2)** constant if `*this->storage() == *other.storage()`,
592  
            otherwise linear in the sizes of `*this` and `other`.
592  
            otherwise linear in the sizes of `*this` and `other`.
593  
        @li **(3)** linear in the sizes of `*this` and `init`.
593  
        @li **(3)** linear in the sizes of `*this` and `init`.
594  
        @li **(4)**--**(16)** linear in the size of `*this`.
594  
        @li **(4)**--**(16)** linear in the size of `*this`.
595  
        @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`.
595  
        @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`.
596  
        @li **(18)** linear in the size of `*this` and `std::strlen(s)`.
596  
        @li **(18)** linear in the size of `*this` and `std::strlen(s)`.
597  
        @li **(22)** constant if `*this->storage() == *s.storage()`,
597  
        @li **(22)** constant if `*this->storage() == *s.storage()`,
598  
            otherwise linear in the size of `*this` and `s.size()`.
598  
            otherwise linear in the size of `*this` and `s.size()`.
599  
        @li **(21)** linear in the size of `*this` and `arr.size()`.
599  
        @li **(21)** linear in the size of `*this` and `arr.size()`.
600  
        @li **(22)** constant if `*this->storage() == *arr.storage()`,
600  
        @li **(22)** constant if `*this->storage() == *arr.storage()`,
601  
            otherwise linear in the size of `*this` and `arr.size()`.
601  
            otherwise linear in the size of `*this` and `arr.size()`.
602  
        @li **(23)** linear in the size of `*this` and `obj.size()`.
602  
        @li **(23)** linear in the size of `*this` and `obj.size()`.
603  
        @li **(24)** constant if `*this->storage() == *obj.storage()`,
603  
        @li **(24)** constant if `*this->storage() == *obj.storage()`,
604  
            otherwise linear in the size of `*this` and `obj.size()`.
604  
            otherwise linear in the size of `*this` and `obj.size()`.
605  

605  

606  
        The size of `*this` is either the size of the underlying container
606  
        The size of `*this` is either the size of the underlying container
607  
        (if there is one), or can be considered to be 1.
607  
        (if there is one), or can be considered to be 1.
608  

608  

609  
        @par Exception Safety
609  
        @par Exception Safety
610  
        @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee.
610  
        @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee.
611  
        @li **(4)**--**(16)** no-throw guarantee.
611  
        @li **(4)**--**(16)** no-throw guarantee.
612  

612  

613  
        Calls to `memory_resource::allocate` may throw.
613  
        Calls to `memory_resource::allocate` may throw.
614  

614  

615  
        @param other The source value.
615  
        @param other The source value.
616  

616  

617  
        @{
617  
        @{
618  
    */
618  
    */
619  
    BOOST_JSON_DECL
619  
    BOOST_JSON_DECL
620  
    value&
620  
    value&
621  
    operator=(value const& other);
621  
    operator=(value const& other);
622  

622  

623  
    /** Overload
623  
    /** Overload
624  

624  

625  
        The contents of the value are replaced with the
625  
        The contents of the value are replaced with the
626  
        contents of `other` using move semantics:
626  
        contents of `other` using move semantics:
627  

627  

628  
        @li If `*other.storage() == *sp`, ownership of
628  
        @li If `*other.storage() == *sp`, ownership of
629  
        the underlying memory is transferred in constant
629  
        the underlying memory is transferred in constant
630  
        time, with no possibility of exceptions.
630  
        time, with no possibility of exceptions.
631  
        After assignment, the moved-from value becomes
631  
        After assignment, the moved-from value becomes
632  
        a null with its current storage pointer.
632  
        a null with its current storage pointer.
633  

633  

634  
        @li If `*other.storage() != *sp`, an
634  
        @li If `*other.storage() != *sp`, an
635  
        element-wise copy is performed if
635  
        element-wise copy is performed if
636  
        `other.is_structured() == true`, which may throw.
636  
        `other.is_structured() == true`, which may throw.
637  
        In this case, the moved-from value is not
637  
        In this case, the moved-from value is not
638  
        changed.
638  
        changed.
639  
    */
639  
    */
640  
    BOOST_JSON_DECL
640  
    BOOST_JSON_DECL
641  
    value&
641  
    value&
642  
    operator=(value&& other);
642  
    operator=(value&& other);
643  

643  

644  
    /** Overload
644  
    /** Overload
645  

645  

646  
        @param init The initializer list to assign from.
646  
        @param init The initializer list to assign from.
647  
    */
647  
    */
648  
    BOOST_JSON_DECL
648  
    BOOST_JSON_DECL
649  
    value&
649  
    value&
650  
    operator=(
650  
    operator=(
651  
        std::initializer_list<value_ref> init);
651  
        std::initializer_list<value_ref> init);
652  

652  

653  
    /// Overload
653  
    /// Overload
654  
    value&
654  
    value&
655  
    operator=(std::nullptr_t) noexcept
655  
    operator=(std::nullptr_t) noexcept
656  
    {
656  
    {
657  
        if(is_scalar())
657  
        if(is_scalar())
658  
        {
658  
        {
659  
            sca_.k = json::kind::null;
659  
            sca_.k = json::kind::null;
660  
        }
660  
        }
661  
        else
661  
        else
662  
        {
662  
        {
663  
            ::new(&sca_) scalar(
663  
            ::new(&sca_) scalar(
664  
                destroy());
664  
                destroy());
665  
        }
665  
        }
666  
        return *this;
666  
        return *this;
667  
    }
667  
    }
668  

668  

669  
    /** Overload
669  
    /** Overload
670  

670  

671  
        @param b The new value.
671  
        @param b The new value.
672  
    */
672  
    */
673  
#ifdef BOOST_JSON_DOCS
673  
#ifdef BOOST_JSON_DOCS
674  
    value& operator=(bool b) noexcept;
674  
    value& operator=(bool b) noexcept;
675  
#else
675  
#else
676  
    template<class T
676  
    template<class T
677  
        ,class = typename std::enable_if<
677  
        ,class = typename std::enable_if<
678  
            std::is_same<T, bool>::value>::type
678  
            std::is_same<T, bool>::value>::type
679  
    >
679  
    >
680  
    value& operator=(T b) noexcept
680  
    value& operator=(T b) noexcept
681  
    {
681  
    {
682  
        if(is_scalar())
682  
        if(is_scalar())
683  
        {
683  
        {
684  
            sca_.b = b;
684  
            sca_.b = b;
685  
            sca_.k = json::kind::bool_;
685  
            sca_.k = json::kind::bool_;
686  
        }
686  
        }
687  
        else
687  
        else
688  
        {
688  
        {
689  
            ::new(&sca_) scalar(
689  
            ::new(&sca_) scalar(
690  
                b, destroy());
690  
                b, destroy());
691  
        }
691  
        }
692  
        return *this;
692  
        return *this;
693  
    }
693  
    }
694  
#endif
694  
#endif
695  

695  

696  
    /** Overload
696  
    /** Overload
697  

697  

698  
        @param i The new value.
698  
        @param i The new value.
699  
    */
699  
    */
700  
    value& operator=(signed char i) noexcept
700  
    value& operator=(signed char i) noexcept
701  
    {
701  
    {
702  
        return operator=(
702  
        return operator=(
703  
            static_cast<long long>(i));
703  
            static_cast<long long>(i));
704  
    }
704  
    }
705  

705  

706  
    /// Overload
706  
    /// Overload
707  
    value& operator=(short i) noexcept
707  
    value& operator=(short i) noexcept
708  
    {
708  
    {
709  
        return operator=(
709  
        return operator=(
710  
            static_cast<long long>(i));
710  
            static_cast<long long>(i));
711  
    }
711  
    }
712  

712  

713  
    /// Overload
713  
    /// Overload
714  
    value& operator=(int i) noexcept
714  
    value& operator=(int i) noexcept
715  
    {
715  
    {
716  
        return operator=(
716  
        return operator=(
717  
            static_cast<long long>(i));
717  
            static_cast<long long>(i));
718  
    }
718  
    }
719  

719  

720  
    /// Overload
720  
    /// Overload
721  
    value& operator=(long i) noexcept
721  
    value& operator=(long i) noexcept
722  
    {
722  
    {
723  
        return operator=(
723  
        return operator=(
724  
            static_cast<long long>(i));
724  
            static_cast<long long>(i));
725  
    }
725  
    }
726  

726  

727  
    /// Overload
727  
    /// Overload
728  
    value& operator=(long long i) noexcept
728  
    value& operator=(long long i) noexcept
729  
    {
729  
    {
730  
        if(is_scalar())
730  
        if(is_scalar())
731  
        {
731  
        {
732  
            sca_.i = i;
732  
            sca_.i = i;
733  
            sca_.k = json::kind::int64;
733  
            sca_.k = json::kind::int64;
734  
        }
734  
        }
735  
        else
735  
        else
736  
        {
736  
        {
737  
            ::new(&sca_) scalar(static_cast<
737  
            ::new(&sca_) scalar(static_cast<
738  
                std::int64_t>(i), destroy());
738  
                std::int64_t>(i), destroy());
739  
        }
739  
        }
740  
        return *this;
740  
        return *this;
741  
    }
741  
    }
742  

742  

743  
    /** Overload
743  
    /** Overload
744  

744  

745  
        @param u The new value.
745  
        @param u The new value.
746  
    */
746  
    */
747  
    value& operator=(unsigned char u) noexcept
747  
    value& operator=(unsigned char u) noexcept
748  
    {
748  
    {
749  
        return operator=(static_cast<
749  
        return operator=(static_cast<
750  
            unsigned long long>(u));
750  
            unsigned long long>(u));
751  
    }
751  
    }
752  

752  

753  
    /// Overload
753  
    /// Overload
754  
    value& operator=(unsigned short u) noexcept
754  
    value& operator=(unsigned short u) noexcept
755  
    {
755  
    {
756  
        return operator=(static_cast<
756  
        return operator=(static_cast<
757  
            unsigned long long>(u));
757  
            unsigned long long>(u));
758  
    }
758  
    }
759  

759  

760  
    /// Overload
760  
    /// Overload
761  
    value& operator=(unsigned int u) noexcept
761  
    value& operator=(unsigned int u) noexcept
762  
    {
762  
    {
763  
        return operator=(static_cast<
763  
        return operator=(static_cast<
764  
            unsigned long long>(u));
764  
            unsigned long long>(u));
765  
    }
765  
    }
766  

766  

767  
    /// Overload
767  
    /// Overload
768  
    value& operator=(unsigned long u) noexcept
768  
    value& operator=(unsigned long u) noexcept
769  
    {
769  
    {
770  
        return operator=(static_cast<
770  
        return operator=(static_cast<
771  
            unsigned long long>(u));
771  
            unsigned long long>(u));
772  
    }
772  
    }
773  

773  

774  
    /// Overload
774  
    /// Overload
775  
    value& operator=(unsigned long long u) noexcept
775  
    value& operator=(unsigned long long u) noexcept
776  
    {
776  
    {
777  
        if(is_scalar())
777  
        if(is_scalar())
778  
        {
778  
        {
779  
            sca_.u = u;
779  
            sca_.u = u;
780  
            sca_.k = json::kind::uint64;
780  
            sca_.k = json::kind::uint64;
781  
        }
781  
        }
782  
        else
782  
        else
783  
        {
783  
        {
784  
            ::new(&sca_) scalar(static_cast<
784  
            ::new(&sca_) scalar(static_cast<
785  
                std::uint64_t>(u), destroy());
785  
                std::uint64_t>(u), destroy());
786  
        }
786  
        }
787  
        return *this;
787  
        return *this;
788  
    }
788  
    }
789  

789  

790  
    /** Overload
790  
    /** Overload
791  

791  

792  
        @param d The new value.
792  
        @param d The new value.
793  
    */
793  
    */
794  
    value& operator=(double d) noexcept
794  
    value& operator=(double d) noexcept
795  
    {
795  
    {
796  
        if(is_scalar())
796  
        if(is_scalar())
797  
        {
797  
        {
798  
            sca_.d = d;
798  
            sca_.d = d;
799  
            sca_.k = json::kind::double_;
799  
            sca_.k = json::kind::double_;
800  
        }
800  
        }
801  
        else
801  
        else
802  
        {
802  
        {
803  
            ::new(&sca_) scalar(
803  
            ::new(&sca_) scalar(
804  
                d, destroy());
804  
                d, destroy());
805  
        }
805  
        }
806  
        return *this;
806  
        return *this;
807  
    }
807  
    }
808  

808  

809  
    /** Overload
809  
    /** Overload
810  

810  

811  
        @param s The new string.
811  
        @param s The new string.
812  
    */
812  
    */
813  
    BOOST_JSON_DECL
813  
    BOOST_JSON_DECL
814  
    value& operator=(string_view s);
814  
    value& operator=(string_view s);
815  

815  

816  
    /// Overload
816  
    /// Overload
817  
    BOOST_JSON_DECL
817  
    BOOST_JSON_DECL
818  
    value& operator=(char const* s);
818  
    value& operator=(char const* s);
819  

819  

820  
    /// Overload
820  
    /// Overload
821  
    BOOST_JSON_DECL
821  
    BOOST_JSON_DECL
822  
    value& operator=(string const& s);
822  
    value& operator=(string const& s);
823  

823  

824  
    /** Overload
824  
    /** Overload
825  

825  

826  
        The contents of the value are replaced with the
826  
        The contents of the value are replaced with the
827  
        contents of `s` using move semantics:
827  
        contents of `s` using move semantics:
828  

828  

829  
        @li If `*other.storage() == *this->storage()`,
829  
        @li If `*other.storage() == *this->storage()`,
830  
        ownership of the underlying memory is transferred
830  
        ownership of the underlying memory is transferred
831  
        in constant time, with no possibility of exceptions.
831  
        in constant time, with no possibility of exceptions.
832  
        After assignment, the moved-from string becomes
832  
        After assignment, the moved-from string becomes
833  
        empty with its current storage pointer.
833  
        empty with its current storage pointer.
834  

834  

835  
        @li If `*other.storage() != *this->storage()`, an
835  
        @li If `*other.storage() != *this->storage()`, an
836  
        element-wise copy is performed, which may throw.
836  
        element-wise copy is performed, which may throw.
837  
        In this case, the moved-from string is not
837  
        In this case, the moved-from string is not
838  
        changed.
838  
        changed.
839  

839  

840  
        @param s The string to move-assign from.
840  
        @param s The string to move-assign from.
841  
    */
841  
    */
842  
    BOOST_JSON_DECL
842  
    BOOST_JSON_DECL
843  
    value& operator=(string&& s);
843  
    value& operator=(string&& s);
844  

844  

845  
    /** Overload
845  
    /** Overload
846  

846  

847  
        Replace `*this` with a copy of the array `arr`.
847  
        Replace `*this` with a copy of the array `arr`.
848  

848  

849  
        @par Exception Safety
849  
        @par Exception Safety
850  
        Strong guarantee.
850  
        Strong guarantee.
851  
        Calls to `memory_resource::allocate` may throw.
851  
        Calls to `memory_resource::allocate` may throw.
852  

852  

853  
        @par Complexity
853  
        @par Complexity
854  
        Linear in the sum of sizes of `*this` and `arr`
854  
        Linear in the sum of sizes of `*this` and `arr`
855  

855  

856  
        @param arr The new array.
856  
        @param arr The new array.
857  
    */
857  
    */
858  
    BOOST_JSON_DECL
858  
    BOOST_JSON_DECL
859  
    value& operator=(array const& arr);
859  
    value& operator=(array const& arr);
860  

860  

861  
    /** Overload
861  
    /** Overload
862  

862  

863  
        The contents of the value are replaced with the
863  
        The contents of the value are replaced with the
864  
        contents of `arr` using move semantics:
864  
        contents of `arr` using move semantics:
865  

865  

866  
        @li If `*arr.storage() == *this->storage()`,
866  
        @li If `*arr.storage() == *this->storage()`,
867  
        ownership of the underlying memory is transferred
867  
        ownership of the underlying memory is transferred
868  
        in constant time, with no possibility of exceptions.
868  
        in constant time, with no possibility of exceptions.
869  
        After assignment, the moved-from array becomes
869  
        After assignment, the moved-from array becomes
870  
        empty with its current storage pointer.
870  
        empty with its current storage pointer.
871  

871  

872  
        @li If `*arr.storage() != *this->storage()`, an
872  
        @li If `*arr.storage() != *this->storage()`, an
873  
        element-wise copy is performed, which may throw.
873  
        element-wise copy is performed, which may throw.
874  
        In this case, the moved-from array is not
874  
        In this case, the moved-from array is not
875  
        changed.
875  
        changed.
876  

876  

877  
        @par Complexity
877  
        @par Complexity
878  
        Constant, or linear in the size of `*this` plus `arr.size()`.
878  
        Constant, or linear in the size of `*this` plus `arr.size()`.
879  

879  

880  
        @par Exception Safety
880  
        @par Exception Safety
881  
        Strong guarantee.
881  
        Strong guarantee.
882  
        Calls to `memory_resource::allocate` may throw.
882  
        Calls to `memory_resource::allocate` may throw.
883  

883  

884  
        @param arr The array to move-assign from.
884  
        @param arr The array to move-assign from.
885  
    */
885  
    */
886  
    BOOST_JSON_DECL
886  
    BOOST_JSON_DECL
887  
    value& operator=(array&& arr);
887  
    value& operator=(array&& arr);
888  

888  

889  
    /** Overload
889  
    /** Overload
890  

890  

891  
        Replace `*this` with a copy of the obect `obj`.
891  
        Replace `*this` with a copy of the obect `obj`.
892  

892  

893  
        @par Exception Safety
893  
        @par Exception Safety
894  
        Strong guarantee.
894  
        Strong guarantee.
895  
        Calls to `memory_resource::allocate` may throw.
895  
        Calls to `memory_resource::allocate` may throw.
896  

896  

897  
        @par Complexity
897  
        @par Complexity
898  
        Linear in the sum of sizes of `*this` and `obj`
898  
        Linear in the sum of sizes of `*this` and `obj`
899  

899  

900  
        @param obj The new object.
900  
        @param obj The new object.
901  
    */
901  
    */
902  
    BOOST_JSON_DECL
902  
    BOOST_JSON_DECL
903  
    value& operator=(object const& obj);
903  
    value& operator=(object const& obj);
904  

904  

905  
    /** Overload
905  
    /** Overload
906  

906  

907  
        The contents of the value are replaced with the
907  
        The contents of the value are replaced with the
908  
        contents of `obj` using move semantics:
908  
        contents of `obj` using move semantics:
909  

909  

910  
        @li If `*obj.storage() == *this->storage()`,
910  
        @li If `*obj.storage() == *this->storage()`,
911  
        ownership of the underlying memory is transferred
911  
        ownership of the underlying memory is transferred
912  
        in constant time, with no possibility of exceptions.
912  
        in constant time, with no possibility of exceptions.
913  
        After assignment, the moved-from object becomes
913  
        After assignment, the moved-from object becomes
914  
        empty with its current storage pointer.
914  
        empty with its current storage pointer.
915  

915  

916  
        @li If `*obj.storage() != *this->storage()`, an
916  
        @li If `*obj.storage() != *this->storage()`, an
917  
        element-wise copy is performed, which may throw.
917  
        element-wise copy is performed, which may throw.
918  
        In this case, the moved-from object is not
918  
        In this case, the moved-from object is not
919  
        changed.
919  
        changed.
920  

920  

921  
        @par Complexity
921  
        @par Complexity
922  
        Constant, or linear in the size of `*this` plus `obj.size()`.
922  
        Constant, or linear in the size of `*this` plus `obj.size()`.
923  

923  

924  
        @par Exception Safety
924  
        @par Exception Safety
925  
        Strong guarantee.
925  
        Strong guarantee.
926  
        Calls to `memory_resource::allocate` may throw.
926  
        Calls to `memory_resource::allocate` may throw.
927  

927  

928  
        @param obj The object to move-assign from.
928  
        @param obj The object to move-assign from.
929  
    */
929  
    */
930  
    BOOST_JSON_DECL
930  
    BOOST_JSON_DECL
931  
    value& operator=(object&& obj);
931  
    value& operator=(object&& obj);
932  
    /// @}
932  
    /// @}
933  

933  

934  
    //------------------------------------------------------
934  
    //------------------------------------------------------
935  
    //
935  
    //
936  
    // Modifiers
936  
    // Modifiers
937  
    //
937  
    //
938  
    //------------------------------------------------------
938  
    //------------------------------------------------------
939  

939  

940  
    /** Replace with a null value.
940  
    /** Replace with a null value.
941  

941  

942  
        The current value is destroyed and the kind is changed to kind::null.
942  
        The current value is destroyed and the kind is changed to kind::null.
943  
        The associated memeory resource is kept unchanged.
943  
        The associated memeory resource is kept unchanged.
944  

944  

945  
        @par Complexity
945  
        @par Complexity
946  
        Linear in the size of `*this`.
946  
        Linear in the size of `*this`.
947  

947  

948  
        @par Exception Safety
948  
        @par Exception Safety
949  
        No-throw guarantee.
949  
        No-throw guarantee.
950  
    */
950  
    */
951  
    void
951  
    void
952  
    emplace_null() noexcept
952  
    emplace_null() noexcept
953  
    {
953  
    {
954  
        *this = nullptr;
954  
        *this = nullptr;
955  
    }
955  
    }
956  

956  

957  
    /** Replace with a `bool` value.
957  
    /** Replace with a `bool` value.
958  

958  

959  
        The value is replaced with a `bool` initialized to `false`, destroying
959  
        The value is replaced with a `bool` initialized to `false`, destroying
960  
        the previous contents, but keeping the memeory resource.
960  
        the previous contents, but keeping the memeory resource.
961  

961  

962  
        @par Complexity
962  
        @par Complexity
963  
        Linear in the size of `*this`.
963  
        Linear in the size of `*this`.
964  

964  

965  
        @par Exception Safety
965  
        @par Exception Safety
966  
        No-throw guarantee.
966  
        No-throw guarantee.
967  

967  

968  
        @return `this->get_bool()`.
968  
        @return `this->get_bool()`.
969  
    */
969  
    */
970  
    bool&
970  
    bool&
971  
    emplace_bool() noexcept
971  
    emplace_bool() noexcept
972  
    {
972  
    {
973  
        *this = false;
973  
        *this = false;
974  
        return sca_.b;
974  
        return sca_.b;
975  
    }
975  
    }
976  

976  

977  
    /** Replace with a `std::int64_t` value.
977  
    /** Replace with a `std::int64_t` value.
978  

978  

979  
        The value is replaced with a `std::int64_t` initialized to zero,
979  
        The value is replaced with a `std::int64_t` initialized to zero,
980  
        destroying the previous contents, but keeping the memeory resource.
980  
        destroying the previous contents, but keeping the memeory resource.
981  

981  

982  
        @par Complexity
982  
        @par Complexity
983  
        Linear in the size of `*this`.
983  
        Linear in the size of `*this`.
984  

984  

985  
        @par Exception Safety
985  
        @par Exception Safety
986  
        No-throw guarantee.
986  
        No-throw guarantee.
987  

987  

988  
        @return `this->get_int64()`.
988  
        @return `this->get_int64()`.
989  
    */
989  
    */
990  
    std::int64_t&
990  
    std::int64_t&
991  
    emplace_int64() noexcept
991  
    emplace_int64() noexcept
992  
    {
992  
    {
993  
        *this = std::int64_t{};
993  
        *this = std::int64_t{};
994  
        return sca_.i;
994  
        return sca_.i;
995  
    }
995  
    }
996  

996  

997  
    /** Replace with a `std::uint64_t` value.
997  
    /** Replace with a `std::uint64_t` value.
998  

998  

999  
        The value is replaced with a `std::uint64_t` initialized to zero,
999  
        The value is replaced with a `std::uint64_t` initialized to zero,
1000  
        destroying the the previous contents, but keeping the memeory resource.
1000  
        destroying the the previous contents, but keeping the memeory resource.
1001  

1001  

1002  
        @par Complexity
1002  
        @par Complexity
1003  
        Linear in the size of `*this`.
1003  
        Linear in the size of `*this`.
1004  

1004  

1005  
        @par Exception Safety
1005  
        @par Exception Safety
1006  
        No-throw guarantee.
1006  
        No-throw guarantee.
1007  

1007  

1008  
        @return `this->get_uint64()`.
1008  
        @return `this->get_uint64()`.
1009  
    */
1009  
    */
1010  
    std::uint64_t&
1010  
    std::uint64_t&
1011  
    emplace_uint64() noexcept
1011  
    emplace_uint64() noexcept
1012  
    {
1012  
    {
1013  
        *this = std::uint64_t{};
1013  
        *this = std::uint64_t{};
1014  
        return sca_.u;
1014  
        return sca_.u;
1015  
    }
1015  
    }
1016  

1016  

1017  
    /** Replace with a `double` value.
1017  
    /** Replace with a `double` value.
1018  

1018  

1019  
        The value is replaced with a `double` initialized to zero, destroying
1019  
        The value is replaced with a `double` initialized to zero, destroying
1020  
        the previous contents, but keeping the memeory resource.
1020  
        the previous contents, but keeping the memeory resource.
1021  

1021  

1022  
        @par Complexity
1022  
        @par Complexity
1023  
        Linear in the size of `*this`.
1023  
        Linear in the size of `*this`.
1024  

1024  

1025  
        @par Exception Safety
1025  
        @par Exception Safety
1026  
        No-throw guarantee.
1026  
        No-throw guarantee.
1027  

1027  

1028  
        @return `this->get_double()`.
1028  
        @return `this->get_double()`.
1029  
    */
1029  
    */
1030  
    double&
1030  
    double&
1031  
    emplace_double() noexcept
1031  
    emplace_double() noexcept
1032  
    {
1032  
    {
1033  
        *this = double{};
1033  
        *this = double{};
1034  
        return sca_.d;
1034  
        return sca_.d;
1035  
    }
1035  
    }
1036  

1036  

1037  
    /** Replace with an empty @ref string.
1037  
    /** Replace with an empty @ref string.
1038  

1038  

1039  
        The value is replaced with an empty @ref string using the current
1039  
        The value is replaced with an empty @ref string using the current
1040  
        memory resource, destroying the previous contents. All previously
1040  
        memory resource, destroying the previous contents. All previously
1041  
        obtained iterators and references obtained beforehand are invalidated.
1041  
        obtained iterators and references obtained beforehand are invalidated.
1042  

1042  

1043  
        @par Complexity
1043  
        @par Complexity
1044  
        Linear in the size of `*this`.
1044  
        Linear in the size of `*this`.
1045  

1045  

1046  
        @par Exception Safety
1046  
        @par Exception Safety
1047  
        No-throw guarantee.
1047  
        No-throw guarantee.
1048  

1048  

1049  
        @return `this->get_string()`.
1049  
        @return `this->get_string()`.
1050  
    */
1050  
    */
1051  
    BOOST_JSON_DECL
1051  
    BOOST_JSON_DECL
1052  
    string&
1052  
    string&
1053  
    emplace_string() noexcept;
1053  
    emplace_string() noexcept;
1054  

1054  

1055  
    /** Replace with an empty array.
1055  
    /** Replace with an empty array.
1056  

1056  

1057  
        The value is replaced with an empty @ref array using the current memory
1057  
        The value is replaced with an empty @ref array using the current memory
1058  
        resource, destroying the previous contents. All previously obtained
1058  
        resource, destroying the previous contents. All previously obtained
1059  
        iterators and references obtained beforehand are invalidated.
1059  
        iterators and references obtained beforehand are invalidated.
1060  

1060  

1061  
        @par Complexity
1061  
        @par Complexity
1062  
        Linear in the size of `*this`.
1062  
        Linear in the size of `*this`.
1063  

1063  

1064  
        @par Exception Safety
1064  
        @par Exception Safety
1065  
        No-throw guarantee.
1065  
        No-throw guarantee.
1066  

1066  

1067  
        @return `this->get_array()`.
1067  
        @return `this->get_array()`.
1068  
    */
1068  
    */
1069  
    BOOST_JSON_DECL
1069  
    BOOST_JSON_DECL
1070  
    array&
1070  
    array&
1071  
    emplace_array() noexcept;
1071  
    emplace_array() noexcept;
1072  

1072  

1073  
    /** Replace with an empty @ref object.
1073  
    /** Replace with an empty @ref object.
1074  

1074  

1075  
        The value is replaced with an empty @ref array using the current memory
1075  
        The value is replaced with an empty @ref array using the current memory
1076  
        resource, destroying the previous contents. All previously obtained
1076  
        resource, destroying the previous contents. All previously obtained
1077  
        iterators and references obtained beforehand are invalidated.
1077  
        iterators and references obtained beforehand are invalidated.
1078  

1078  

1079  
        @par Complexity
1079  
        @par Complexity
1080  
        Linear in the size of `*this`.
1080  
        Linear in the size of `*this`.
1081  

1081  

1082  
        @par Exception Safety
1082  
        @par Exception Safety
1083  
        No-throw guarantee.
1083  
        No-throw guarantee.
1084  

1084  

1085  
        @return `this->get_object()`.
1085  
        @return `this->get_object()`.
1086  
    */
1086  
    */
1087  
    BOOST_JSON_DECL
1087  
    BOOST_JSON_DECL
1088  
    object&
1088  
    object&
1089  
    emplace_object() noexcept;
1089  
    emplace_object() noexcept;
1090  

1090  

1091  
    /** Swap the given values.
1091  
    /** Swap the given values.
1092  

1092  

1093  
        Exchanges the contents of this value with another value. Ownership of
1093  
        Exchanges the contents of this value with another value. Ownership of
1094  
        the respective @ref boost::container::pmr::memory_resource objects is
1094  
        the respective @ref boost::container::pmr::memory_resource objects is
1095  
        not transferred:
1095  
        not transferred:
1096  

1096  

1097  
        @li If `this == &other`, this function has no effect.
1097  
        @li If `this == &other`, this function has no effect.
1098  
        @li If `*other.storage() == *this->storage()`, ownership of the
1098  
        @li If `*other.storage() == *this->storage()`, ownership of the
1099  
            underlying memory is swapped in constant time, with no possibility
1099  
            underlying memory is swapped in constant time, with no possibility
1100  
            of exceptions. All iterators and references remain valid.
1100  
            of exceptions. All iterators and references remain valid.
1101  
        @li If `*other.storage() != *this->storage()`, the contents are
1101  
        @li If `*other.storage() != *this->storage()`, the contents are
1102  
            logically swapped by making copies, which can throw. In this case
1102  
            logically swapped by making copies, which can throw. In this case
1103  
            all iterators and references are invalidated.
1103  
            all iterators and references are invalidated.
1104  

1104  

1105  
        @par Complexity
1105  
        @par Complexity
1106  
        Constant or linear in the sum of the sizes of the values.
1106  
        Constant or linear in the sum of the sizes of the values.
1107  

1107  

1108  
        @par Exception Safety
1108  
        @par Exception Safety
1109  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1109  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1110  

1110  

1111  
        @param other The value to swap with.
1111  
        @param other The value to swap with.
1112  
    */
1112  
    */
1113  
    BOOST_JSON_DECL
1113  
    BOOST_JSON_DECL
1114  
    void
1114  
    void
1115  
    swap(value& other);
1115  
    swap(value& other);
1116  

1116  

1117  
    /** Swap the given values.
1117  
    /** Swap the given values.
1118  

1118  

1119  
        Exchanges the contents of value `lhs` with another value `rhs`.
1119  
        Exchanges the contents of value `lhs` with another value `rhs`.
1120  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1120  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1121  
        objects is not transferred.
1121  
        objects is not transferred.
1122  

1122  

1123  
        @li If `&lhs == &rhs`, this function call has no effect.
1123  
        @li If `&lhs == &rhs`, this function call has no effect.
1124  
        @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1124  
        @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1125  
            memory is swapped in constant time, with no possibility of
1125  
            memory is swapped in constant time, with no possibility of
1126  
            exceptions. All iterators and references remain valid.
1126  
            exceptions. All iterators and references remain valid.
1127  
        @li If `*lhs.storage() != *rhs.storage`, the contents are logically
1127  
        @li If `*lhs.storage() != *rhs.storage`, the contents are logically
1128  
            swapped by a copy, which can throw. In this case all iterators and
1128  
            swapped by a copy, which can throw. In this case all iterators and
1129  
            references are invalidated.
1129  
            references are invalidated.
1130  

1130  

1131  
        @par Complexity
1131  
        @par Complexity
1132  
        Constant or linear in the sum of the sizes of the values.
1132  
        Constant or linear in the sum of the sizes of the values.
1133  

1133  

1134  
        @par Exception Safety
1134  
        @par Exception Safety
1135  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1135  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1136  

1136  

1137  
        @param lhs The value to exchange.
1137  
        @param lhs The value to exchange.
1138  
        @param rhs The value to exchange.
1138  
        @param rhs The value to exchange.
1139  

1139  

1140  
        @see @ref value::swap
1140  
        @see @ref value::swap
1141  
    */
1141  
    */
1142  
    friend
1142  
    friend
1143  
    void
1143  
    void
1144  
    swap(value& lhs, value& rhs)
1144  
    swap(value& lhs, value& rhs)
1145  
    {
1145  
    {
1146  
        lhs.swap(rhs);
1146  
        lhs.swap(rhs);
1147  
    }
1147  
    }
1148  

1148  

1149  
    //------------------------------------------------------
1149  
    //------------------------------------------------------
1150  
    //
1150  
    //
1151  
    // Observers
1151  
    // Observers
1152  
    //
1152  
    //
1153  
    //------------------------------------------------------
1153  
    //------------------------------------------------------
1154  

1154  

1155  
    /** Returns the kind of this JSON value.
1155  
    /** Returns the kind of this JSON value.
1156  

1156  

1157  
        This function returns the discriminating enumeration constant of type
1157  
        This function returns the discriminating enumeration constant of type
1158  
        @ref json::kind corresponding to the underlying representation stored
1158  
        @ref json::kind corresponding to the underlying representation stored
1159  
        in the container.
1159  
        in the container.
1160  

1160  

1161  
        @par Complexity
1161  
        @par Complexity
1162  
        Constant.
1162  
        Constant.
1163  

1163  

1164  
        @par Exception Safety
1164  
        @par Exception Safety
1165  
        No-throw guarantee.
1165  
        No-throw guarantee.
1166  
    */
1166  
    */
1167  
    json::kind
1167  
    json::kind
1168  
    kind() const noexcept
1168  
    kind() const noexcept
1169  
    {
1169  
    {
1170  
        return static_cast<json::kind>(
1170  
        return static_cast<json::kind>(
1171  
            static_cast<unsigned char>(
1171  
            static_cast<unsigned char>(
1172  
                sca_.k) & 0x3f);
1172  
                sca_.k) & 0x3f);
1173  
    }
1173  
    }
1174  

1174  

1175  
    /** Check if this is an @ref array.
1175  
    /** Check if this is an @ref array.
1176  

1176  

1177  
        Returns `true` if the value's @ref kind() is `kind::array`.
1177  
        Returns `true` if the value's @ref kind() is `kind::array`.
1178  

1178  

1179  
        @returns `this->kind() == kind::array`.
1179  
        @returns `this->kind() == kind::array`.
1180  

1180  

1181  
        @par Complexity
1181  
        @par Complexity
1182  
        Constant.
1182  
        Constant.
1183  

1183  

1184  
        @par Exception Safety
1184  
        @par Exception Safety
1185  
        No-throw guarantee.
1185  
        No-throw guarantee.
1186  
    */
1186  
    */
1187  
    bool
1187  
    bool
1188  
    is_array() const noexcept
1188  
    is_array() const noexcept
1189  
    {
1189  
    {
1190  
        return kind() == json::kind::array;
1190  
        return kind() == json::kind::array;
1191  
    }
1191  
    }
1192  

1192  

1193  
    /** Check if this is an @ref object.
1193  
    /** Check if this is an @ref object.
1194  

1194  

1195  
        Returns `true` if the value's @ref kind() is `kind::object`.
1195  
        Returns `true` if the value's @ref kind() is `kind::object`.
1196  

1196  

1197  
        @returns `this->kind() == kind::object`.
1197  
        @returns `this->kind() == kind::object`.
1198  

1198  

1199  
        @par Complexity
1199  
        @par Complexity
1200  
        Constant.
1200  
        Constant.
1201  

1201  

1202  
        @par Exception Safety
1202  
        @par Exception Safety
1203  
        No-throw guarantee.
1203  
        No-throw guarantee.
1204  
    */
1204  
    */
1205  
    bool
1205  
    bool
1206  
    is_object() const noexcept
1206  
    is_object() const noexcept
1207  
    {
1207  
    {
1208  
        return kind() == json::kind::object;
1208  
        return kind() == json::kind::object;
1209  
    }
1209  
    }
1210  

1210  

1211  
    /** Check if this is a @ref string.
1211  
    /** Check if this is a @ref string.
1212  

1212  

1213  
        Returns `true` if the value's @ref kind() is `kind::string`.
1213  
        Returns `true` if the value's @ref kind() is `kind::string`.
1214  

1214  

1215  
        @returns `this->kind() == kind::string`.
1215  
        @returns `this->kind() == kind::string`.
1216  

1216  

1217  
        @par Complexity
1217  
        @par Complexity
1218  
        Constant.
1218  
        Constant.
1219  

1219  

1220  
        @par Exception Safety
1220  
        @par Exception Safety
1221  
        No-throw guarantee.
1221  
        No-throw guarantee.
1222  
    */
1222  
    */
1223  
    bool
1223  
    bool
1224  
    is_string() const noexcept
1224  
    is_string() const noexcept
1225  
    {
1225  
    {
1226  
        return kind() == json::kind::string;
1226  
        return kind() == json::kind::string;
1227  
    }
1227  
    }
1228  

1228  

1229  
    /** Check if this is a `std::int64_t`.
1229  
    /** Check if this is a `std::int64_t`.
1230  

1230  

1231  
        Returns `true` if the value's @ref kind() is `kind::int64`.
1231  
        Returns `true` if the value's @ref kind() is `kind::int64`.
1232  

1232  

1233  
        @returns `this->kind() == kind::int64`.
1233  
        @returns `this->kind() == kind::int64`.
1234  

1234  

1235  
        @par Complexity
1235  
        @par Complexity
1236  
        Constant.
1236  
        Constant.
1237  

1237  

1238  
        @par Exception Safety
1238  
        @par Exception Safety
1239  
        No-throw guarantee.
1239  
        No-throw guarantee.
1240  
    */
1240  
    */
1241  
    bool
1241  
    bool
1242  
    is_int64() const noexcept
1242  
    is_int64() const noexcept
1243  
    {
1243  
    {
1244  
        return kind() == json::kind::int64;
1244  
        return kind() == json::kind::int64;
1245  
    }
1245  
    }
1246  

1246  

1247  
    /** Checks if this is a `std::uint64_t`.
1247  
    /** Checks if this is a `std::uint64_t`.
1248  

1248  

1249  
        Returns `true` if the value's @ref kind() is `kind::uint64`.
1249  
        Returns `true` if the value's @ref kind() is `kind::uint64`.
1250  

1250  

1251  
        @returns `this->kind() == kind::uint64`.
1251  
        @returns `this->kind() == kind::uint64`.
1252  

1252  

1253  
        @par Complexity
1253  
        @par Complexity
1254  
        Constant.
1254  
        Constant.
1255  

1255  

1256  
        @par Exception Safety
1256  
        @par Exception Safety
1257  
        No-throw guarantee.
1257  
        No-throw guarantee.
1258  
    */
1258  
    */
1259  
    bool
1259  
    bool
1260  
    is_uint64() const noexcept
1260  
    is_uint64() const noexcept
1261  
    {
1261  
    {
1262  
        return kind() == json::kind::uint64;
1262  
        return kind() == json::kind::uint64;
1263  
    }
1263  
    }
1264  

1264  

1265  
    /** Check if this is a `double`.
1265  
    /** Check if this is a `double`.
1266  

1266  

1267  
        Returns `true` if the value's @ref kind() is `kind::double_`.
1267  
        Returns `true` if the value's @ref kind() is `kind::double_`.
1268  

1268  

1269  
        @returns `this->kind() == kind::double_`.
1269  
        @returns `this->kind() == kind::double_`.
1270  

1270  

1271  
        @par Complexity
1271  
        @par Complexity
1272  
        Constant.
1272  
        Constant.
1273  

1273  

1274  
        @par Exception Safety
1274  
        @par Exception Safety
1275  
        No-throw guarantee.
1275  
        No-throw guarantee.
1276  
    */
1276  
    */
1277  
    bool
1277  
    bool
1278  
    is_double() const noexcept
1278  
    is_double() const noexcept
1279  
    {
1279  
    {
1280  
        return kind() == json::kind::double_;
1280  
        return kind() == json::kind::double_;
1281  
    }
1281  
    }
1282  

1282  

1283  
    /** Check if this is a `bool`.
1283  
    /** Check if this is a `bool`.
1284  

1284  

1285  
        Returns `true` if the value's @ref kind() is `kind::bool_`.
1285  
        Returns `true` if the value's @ref kind() is `kind::bool_`.
1286  

1286  

1287  
        @returns `this->kind() == kind::bool_`.
1287  
        @returns `this->kind() == kind::bool_`.
1288  

1288  

1289  
        @par Complexity
1289  
        @par Complexity
1290  
        Constant.
1290  
        Constant.
1291  

1291  

1292  
        @par Exception Safety
1292  
        @par Exception Safety
1293  
        No-throw guarantee.
1293  
        No-throw guarantee.
1294  
    */
1294  
    */
1295  
    bool
1295  
    bool
1296  
    is_bool() const noexcept
1296  
    is_bool() const noexcept
1297  
    {
1297  
    {
1298  
        return kind() == json::kind::bool_;
1298  
        return kind() == json::kind::bool_;
1299  
    }
1299  
    }
1300  

1300  

1301  
    /** Check if this is a null value.
1301  
    /** Check if this is a null value.
1302  

1302  

1303  
        Returns `true` if the value's @ref kind() is `kind::null`.
1303  
        Returns `true` if the value's @ref kind() is `kind::null`.
1304  

1304  

1305  
        @returns `this->kind() == kind::null`.
1305  
        @returns `this->kind() == kind::null`.
1306  

1306  

1307  
        @par Complexity
1307  
        @par Complexity
1308  
        Constant.
1308  
        Constant.
1309  

1309  

1310  
        @par Exception Safety
1310  
        @par Exception Safety
1311  
        No-throw guarantee.
1311  
        No-throw guarantee.
1312  
    */
1312  
    */
1313  
    bool
1313  
    bool
1314  
    is_null() const noexcept
1314  
    is_null() const noexcept
1315  
    {
1315  
    {
1316  
        return kind() == json::kind::null;
1316  
        return kind() == json::kind::null;
1317  
    }
1317  
    }
1318  

1318  

1319  
    /** Checks if this is an @ref array or an @ref object.
1319  
    /** Checks if this is an @ref array or an @ref object.
1320  

1320  

1321  
        This function returns `true` if @ref kind() is either `kind::object` or
1321  
        This function returns `true` if @ref kind() is either `kind::object` or
1322  
        `kind::array`.
1322  
        `kind::array`.
1323  

1323  

1324  
        @par Complexity
1324  
        @par Complexity
1325  
        Constant.
1325  
        Constant.
1326  

1326  

1327  
        @par Exception Safety
1327  
        @par Exception Safety
1328  
        No-throw guarantee.
1328  
        No-throw guarantee.
1329  
    */
1329  
    */
1330  
    bool
1330  
    bool
1331  
    is_structured() const noexcept
1331  
    is_structured() const noexcept
1332  
    {
1332  
    {
1333  
        // VFALCO Could use bit 0x20 for this
1333  
        // VFALCO Could use bit 0x20 for this
1334  
        return
1334  
        return
1335  
           kind() == json::kind::object ||
1335  
           kind() == json::kind::object ||
1336  
           kind() == json::kind::array;
1336  
           kind() == json::kind::array;
1337  
    }
1337  
    }
1338  

1338  

1339  
    /** Check if this is not an @ref array or @ref object.
1339  
    /** Check if this is not an @ref array or @ref object.
1340  

1340  

1341  
        This function returns `true` if @ref kind() is neither `kind::object`
1341  
        This function returns `true` if @ref kind() is neither `kind::object`
1342  
        nor `kind::array`.
1342  
        nor `kind::array`.
1343  

1343  

1344  
        @par Complexity
1344  
        @par Complexity
1345  
        Constant.
1345  
        Constant.
1346  

1346  

1347  
        @par Exception Safety
1347  
        @par Exception Safety
1348  
        No-throw guarantee.
1348  
        No-throw guarantee.
1349  
    */
1349  
    */
1350  
    bool
1350  
    bool
1351  
    is_primitive() const noexcept
1351  
    is_primitive() const noexcept
1352  
    {
1352  
    {
1353  
        // VFALCO Could use bit 0x20 for this
1353  
        // VFALCO Could use bit 0x20 for this
1354  
        return
1354  
        return
1355  
           sca_.k != json::kind::object &&
1355  
           sca_.k != json::kind::object &&
1356  
           sca_.k != json::kind::array;
1356  
           sca_.k != json::kind::array;
1357  
    }
1357  
    }
1358  

1358  

1359  
    /** Check if this is a number.
1359  
    /** Check if this is a number.
1360  

1360  

1361  
        This function returns `true` when @ref kind() is one of `kind::int64`,
1361  
        This function returns `true` when @ref kind() is one of `kind::int64`,
1362  
        `kind::uint64`, or `kind::double_`.
1362  
        `kind::uint64`, or `kind::double_`.
1363  

1363  

1364  
        @par Complexity
1364  
        @par Complexity
1365  
        Constant.
1365  
        Constant.
1366  

1366  

1367  
        @par Exception Safety
1367  
        @par Exception Safety
1368  
        No-throw guarantee.
1368  
        No-throw guarantee.
1369  
    */
1369  
    */
1370  
    bool
1370  
    bool
1371  
    is_number() const noexcept
1371  
    is_number() const noexcept
1372  
    {
1372  
    {
1373  
        // VFALCO Could use bit 0x40 for this
1373  
        // VFALCO Could use bit 0x40 for this
1374  
        return
1374  
        return
1375  
            kind() == json::kind::int64 ||
1375  
            kind() == json::kind::int64 ||
1376  
            kind() == json::kind::uint64 ||
1376  
            kind() == json::kind::uint64 ||
1377  
            kind() == json::kind::double_;
1377  
            kind() == json::kind::double_;
1378  
    }
1378  
    }
1379  

1379  

1380  
    //------------------------------------------------------
1380  
    //------------------------------------------------------
1381  

1381  

1382  
    /** Return a pointer to the underlying @ref array.
1382  
    /** Return a pointer to the underlying @ref array.
1383  

1383  

1384  
        If `this->kind() == kind::array`, returns a pointer to the underlying
1384  
        If `this->kind() == kind::array`, returns a pointer to the underlying
1385  
        array. Otherwise, returns `nullptr`.
1385  
        array. Otherwise, returns `nullptr`.
1386  

1386  

1387  
        @par Example
1387  
        @par Example
1388  
        The return value is used in both a boolean context and
1388  
        The return value is used in both a boolean context and
1389  
        to assign a variable:
1389  
        to assign a variable:
1390  
        @code
1390  
        @code
1391  
        if( auto p = jv.if_array() )
1391  
        if( auto p = jv.if_array() )
1392  
            return *p;
1392  
            return *p;
1393  
        @endcode
1393  
        @endcode
1394  

1394  

1395  
        @par Complexity
1395  
        @par Complexity
1396  
        Constant.
1396  
        Constant.
1397  

1397  

1398  
        @par Exception Safety
1398  
        @par Exception Safety
1399  
        No-throw guarantee.
1399  
        No-throw guarantee.
1400  

1400  

1401  
        @{
1401  
        @{
1402  
    */
1402  
    */
1403  
    array const*
1403  
    array const*
1404  
    if_array() const noexcept
1404  
    if_array() const noexcept
1405  
    {
1405  
    {
1406  
        if(kind() == json::kind::array)
1406  
        if(kind() == json::kind::array)
1407  
            return &arr_;
1407  
            return &arr_;
1408  
        return nullptr;
1408  
        return nullptr;
1409  
    }
1409  
    }
1410  

1410  

1411  
    array*
1411  
    array*
1412  
    if_array() noexcept
1412  
    if_array() noexcept
1413  
    {
1413  
    {
1414  
        if(kind() == json::kind::array)
1414  
        if(kind() == json::kind::array)
1415  
            return &arr_;
1415  
            return &arr_;
1416  
        return nullptr;
1416  
        return nullptr;
1417  
    }
1417  
    }
1418  
    /// @}
1418  
    /// @}
1419  

1419  

1420  
    /** Return a pointer to the underlying @ref object.
1420  
    /** Return a pointer to the underlying @ref object.
1421  

1421  

1422  
        If `this->kind() == kind::object`, returns a pointer to the underlying
1422  
        If `this->kind() == kind::object`, returns a pointer to the underlying
1423  
        object. Otherwise, returns `nullptr`.
1423  
        object. Otherwise, returns `nullptr`.
1424  

1424  

1425  
        @par Example
1425  
        @par Example
1426  
        The return value is used in both a boolean context and
1426  
        The return value is used in both a boolean context and
1427  
        to assign a variable:
1427  
        to assign a variable:
1428  
        @code
1428  
        @code
1429  
        if( auto p = jv.if_object() )
1429  
        if( auto p = jv.if_object() )
1430  
            return *p;
1430  
            return *p;
1431  
        @endcode
1431  
        @endcode
1432  

1432  

1433  
        @par Complexity
1433  
        @par Complexity
1434  
        Constant.
1434  
        Constant.
1435  

1435  

1436  
        @par Exception Safety
1436  
        @par Exception Safety
1437  
        No-throw guarantee.
1437  
        No-throw guarantee.
1438  

1438  

1439  
        @{
1439  
        @{
1440  
    */
1440  
    */
1441  
    object const*
1441  
    object const*
1442  
    if_object() const noexcept
1442  
    if_object() const noexcept
1443  
    {
1443  
    {
1444  
        if(kind() == json::kind::object)
1444  
        if(kind() == json::kind::object)
1445  
            return &obj_;
1445  
            return &obj_;
1446  
        return nullptr;
1446  
        return nullptr;
1447  
    }
1447  
    }
1448  

1448  

1449  
    object*
1449  
    object*
1450  
    if_object() noexcept
1450  
    if_object() noexcept
1451  
    {
1451  
    {
1452  
        if(kind() == json::kind::object)
1452  
        if(kind() == json::kind::object)
1453  
            return &obj_;
1453  
            return &obj_;
1454  
        return nullptr;
1454  
        return nullptr;
1455  
    }
1455  
    }
1456  
    /// @}
1456  
    /// @}
1457  

1457  

1458  
    /** Return a pointer to the underlying @ref string.
1458  
    /** Return a pointer to the underlying @ref string.
1459  

1459  

1460  
        If `this->kind() == kind::string`, returns a pointer to the underlying
1460  
        If `this->kind() == kind::string`, returns a pointer to the underlying
1461  
        object. Otherwise, returns `nullptr`.
1461  
        object. Otherwise, returns `nullptr`.
1462  

1462  

1463  
        @par Example
1463  
        @par Example
1464  
        The return value is used in both a boolean context and
1464  
        The return value is used in both a boolean context and
1465  
        to assign a variable:
1465  
        to assign a variable:
1466  
        @code
1466  
        @code
1467  
        if( auto p = jv.if_string() )
1467  
        if( auto p = jv.if_string() )
1468  
            return *p;
1468  
            return *p;
1469  
        @endcode
1469  
        @endcode
1470  

1470  

1471  
        @par Complexity
1471  
        @par Complexity
1472  
        Constant.
1472  
        Constant.
1473  

1473  

1474  
        @par Exception Safety
1474  
        @par Exception Safety
1475  
        No-throw guarantee.
1475  
        No-throw guarantee.
1476  

1476  

1477  
        @{
1477  
        @{
1478  
    */
1478  
    */
1479  
    string const*
1479  
    string const*
1480  
    if_string() const noexcept
1480  
    if_string() const noexcept
1481  
    {
1481  
    {
1482  
        if(kind() == json::kind::string)
1482  
        if(kind() == json::kind::string)
1483  
            return &str_;
1483  
            return &str_;
1484  
        return nullptr;
1484  
        return nullptr;
1485  
    }
1485  
    }
1486  

1486  

1487  
    string*
1487  
    string*
1488  
    if_string() noexcept
1488  
    if_string() noexcept
1489  
    {
1489  
    {
1490  
        if(kind() == json::kind::string)
1490  
        if(kind() == json::kind::string)
1491  
            return &str_;
1491  
            return &str_;
1492  
        return nullptr;
1492  
        return nullptr;
1493  
    }
1493  
    }
1494  
    /// @}
1494  
    /// @}
1495  

1495  

1496  
    /** Return a pointer to the underlying `std::int64_t`.
1496  
    /** Return a pointer to the underlying `std::int64_t`.
1497  

1497  

1498  
        If `this->kind() == kind::int64`, returns a pointer to the underlying
1498  
        If `this->kind() == kind::int64`, returns a pointer to the underlying
1499  
        integer. Otherwise, returns `nullptr`.
1499  
        integer. Otherwise, returns `nullptr`.
1500  

1500  

1501  
        @par Example
1501  
        @par Example
1502  
        The return value is used in both a boolean context and
1502  
        The return value is used in both a boolean context and
1503  
        to assign a variable:
1503  
        to assign a variable:
1504  
        @code
1504  
        @code
1505  
        if( auto p = jv.if_int64() )
1505  
        if( auto p = jv.if_int64() )
1506  
            return *p;
1506  
            return *p;
1507  
        @endcode
1507  
        @endcode
1508  

1508  

1509  
        @par Complexity
1509  
        @par Complexity
1510  
        Constant.
1510  
        Constant.
1511  

1511  

1512  
        @par Exception Safety
1512  
        @par Exception Safety
1513  
        No-throw guarantee.
1513  
        No-throw guarantee.
1514  

1514  

1515  
        @{
1515  
        @{
1516  
    */
1516  
    */
1517  
    std::int64_t const*
1517  
    std::int64_t const*
1518  
    if_int64() const noexcept
1518  
    if_int64() const noexcept
1519  
    {
1519  
    {
1520  
        if(kind() == json::kind::int64)
1520  
        if(kind() == json::kind::int64)
1521  
            return &sca_.i;
1521  
            return &sca_.i;
1522  
        return nullptr;
1522  
        return nullptr;
1523  
    }
1523  
    }
1524  

1524  

1525  
    std::int64_t*
1525  
    std::int64_t*
1526  
    if_int64() noexcept
1526  
    if_int64() noexcept
1527  
    {
1527  
    {
1528  
        if(kind() == json::kind::int64)
1528  
        if(kind() == json::kind::int64)
1529  
            return &sca_.i;
1529  
            return &sca_.i;
1530  
        return nullptr;
1530  
        return nullptr;
1531  
    }
1531  
    }
1532  
    /// @}
1532  
    /// @}
1533  

1533  

1534  
    /** Return a pointer to the underlying `std::uint64_t`.
1534  
    /** Return a pointer to the underlying `std::uint64_t`.
1535  

1535  

1536  
        If `this->kind() == kind::uint64`, returns a pointer to the underlying
1536  
        If `this->kind() == kind::uint64`, returns a pointer to the underlying
1537  
        unsigned integer. Otherwise, returns `nullptr`.
1537  
        unsigned integer. Otherwise, returns `nullptr`.
1538  

1538  

1539  
        @par Example
1539  
        @par Example
1540  
        The return value is used in both a boolean context and
1540  
        The return value is used in both a boolean context and
1541  
        to assign a variable:
1541  
        to assign a variable:
1542  
        @code
1542  
        @code
1543  
        if( auto p = jv.if_uint64() )
1543  
        if( auto p = jv.if_uint64() )
1544  
            return *p;
1544  
            return *p;
1545  
        @endcode
1545  
        @endcode
1546  

1546  

1547  
        @par Complexity
1547  
        @par Complexity
1548  
        Constant.
1548  
        Constant.
1549  

1549  

1550  
        @par Exception Safety
1550  
        @par Exception Safety
1551  
        No-throw guarantee.
1551  
        No-throw guarantee.
1552  

1552  

1553  
        @{
1553  
        @{
1554  
    */
1554  
    */
1555  
    std::uint64_t const*
1555  
    std::uint64_t const*
1556  
    if_uint64() const noexcept
1556  
    if_uint64() const noexcept
1557  
    {
1557  
    {
1558  
        if(kind() == json::kind::uint64)
1558  
        if(kind() == json::kind::uint64)
1559  
            return &sca_.u;
1559  
            return &sca_.u;
1560  
        return nullptr;
1560  
        return nullptr;
1561  
    }
1561  
    }
1562  

1562  

1563  
    std::uint64_t*
1563  
    std::uint64_t*
1564  
    if_uint64() noexcept
1564  
    if_uint64() noexcept
1565  
    {
1565  
    {
1566  
        if(kind() == json::kind::uint64)
1566  
        if(kind() == json::kind::uint64)
1567  
            return &sca_.u;
1567  
            return &sca_.u;
1568  
        return nullptr;
1568  
        return nullptr;
1569  
    }
1569  
    }
1570  
    /// @}
1570  
    /// @}
1571  

1571  

1572  
    /** Return a pointer to the underlying `double`.
1572  
    /** Return a pointer to the underlying `double`.
1573  

1573  

1574  
        If `this->kind() == kind::double_`, returns a pointer to the underlying
1574  
        If `this->kind() == kind::double_`, returns a pointer to the underlying
1575  
        double. Otherwise, returns `nullptr`.
1575  
        double. Otherwise, returns `nullptr`.
1576  

1576  

1577  
        @par Example
1577  
        @par Example
1578  
        The return value is used in both a boolean context and
1578  
        The return value is used in both a boolean context and
1579  
        to assign a variable:
1579  
        to assign a variable:
1580  
        @code
1580  
        @code
1581  
        if( auto p = jv.if_double() )
1581  
        if( auto p = jv.if_double() )
1582  
            return *p;
1582  
            return *p;
1583  
        @endcode
1583  
        @endcode
1584  

1584  

1585  
        @par Complexity
1585  
        @par Complexity
1586  
        Constant.
1586  
        Constant.
1587  

1587  

1588  
        @par Exception Safety
1588  
        @par Exception Safety
1589  
        No-throw guarantee.
1589  
        No-throw guarantee.
1590  

1590  

1591  
        @{
1591  
        @{
1592  
    */
1592  
    */
1593  
    double const*
1593  
    double const*
1594  
    if_double() const noexcept
1594  
    if_double() const noexcept
1595  
    {
1595  
    {
1596  
        if(kind() == json::kind::double_)
1596  
        if(kind() == json::kind::double_)
1597  
            return &sca_.d;
1597  
            return &sca_.d;
1598  
        return nullptr;
1598  
        return nullptr;
1599  
    }
1599  
    }
1600  

1600  

1601  
    double*
1601  
    double*
1602  
    if_double() noexcept
1602  
    if_double() noexcept
1603  
    {
1603  
    {
1604  
        if(kind() == json::kind::double_)
1604  
        if(kind() == json::kind::double_)
1605  
            return &sca_.d;
1605  
            return &sca_.d;
1606  
        return nullptr;
1606  
        return nullptr;
1607  
    }
1607  
    }
1608  
    /// @}
1608  
    /// @}
1609  

1609  

1610  
    /** Return a pointer to the underlying `bool` .
1610  
    /** Return a pointer to the underlying `bool` .
1611  

1611  

1612  
        If `this->kind() == kind::bool_`, returns a pointer to the underlying
1612  
        If `this->kind() == kind::bool_`, returns a pointer to the underlying
1613  
        boolean. Otherwise, returns `nullptr`.
1613  
        boolean. Otherwise, returns `nullptr`.
1614  

1614  

1615  
        @par Example
1615  
        @par Example
1616  
        The return value is used in both a boolean context and
1616  
        The return value is used in both a boolean context and
1617  
        to assign a variable:
1617  
        to assign a variable:
1618  
        @code
1618  
        @code
1619  
        if( auto p = jv.if_bool() )
1619  
        if( auto p = jv.if_bool() )
1620  
            return *p;
1620  
            return *p;
1621  
        @endcode
1621  
        @endcode
1622  

1622  

1623  
        @par Complexity
1623  
        @par Complexity
1624  
        Constant.
1624  
        Constant.
1625  

1625  

1626  
        @par Exception Safety
1626  
        @par Exception Safety
1627  
        No-throw guarantee.
1627  
        No-throw guarantee.
1628  

1628  

1629  
        @{
1629  
        @{
1630  
    */
1630  
    */
1631  
    bool const*
1631  
    bool const*
1632  
    if_bool() const noexcept
1632  
    if_bool() const noexcept
1633  
    {
1633  
    {
1634  
        if(kind() == json::kind::bool_)
1634  
        if(kind() == json::kind::bool_)
1635  
            return &sca_.b;
1635  
            return &sca_.b;
1636  
        return nullptr;
1636  
        return nullptr;
1637  
    }
1637  
    }
1638  

1638  

1639  
    bool*
1639  
    bool*
1640  
    if_bool() noexcept
1640  
    if_bool() noexcept
1641  
    {
1641  
    {
1642  
        if(kind() == json::kind::bool_)
1642  
        if(kind() == json::kind::bool_)
1643  
            return &sca_.b;
1643  
            return &sca_.b;
1644  
        return nullptr;
1644  
        return nullptr;
1645  
    }
1645  
    }
1646  
    /// @}
1646  
    /// @}
1647  

1647  

1648  
    //------------------------------------------------------
1648  
    //------------------------------------------------------
1649  

1649  

1650  
    /** Return the stored number cast to an arithmetic type.
1650  
    /** Return the stored number cast to an arithmetic type.
1651  

1651  

1652  
        This function attempts to return the stored value converted to the
1652  
        This function attempts to return the stored value converted to the
1653  
        arithmetic type `T` which may not be `bool`:
1653  
        arithmetic type `T` which may not be `bool`:
1654  

1654  

1655  
        @li If `T` is an integral type and the stored value is a number which
1655  
        @li If `T` is an integral type and the stored value is a number which
1656  
            can be losslessly converted, the conversion is performed without
1656  
            can be losslessly converted, the conversion is performed without
1657  
            error and the converted number is returned.
1657  
            error and the converted number is returned.
1658  
        @li If `T` is an integral type and the stored value is a number which
1658  
        @li If `T` is an integral type and the stored value is a number which
1659  
            cannot be losslessly converted, then the operation fails with
1659  
            cannot be losslessly converted, then the operation fails with
1660  
            an error.
1660  
            an error.
1661  
        @li If `T` is a floating point type and the stored value is a number,
1661  
        @li If `T` is a floating point type and the stored value is a number,
1662  
            the conversion is performed without error. The converted number is
1662  
            the conversion is performed without error. The converted number is
1663  
            returned, with a possible loss of precision.
1663  
            returned, with a possible loss of precision.
1664  
        @li Otherwise, if the stored value is not a number; that is, if
1664  
        @li Otherwise, if the stored value is not a number; that is, if
1665  
            @ref is_number() returns `false`, then the operation fails with
1665  
            @ref is_number() returns `false`, then the operation fails with
1666  
            an error.
1666  
            an error.
1667  

1667  

1668  
        @par Constraints
1668  
        @par Constraints
1669  
        @code
1669  
        @code
1670  
        std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1670  
        std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1671  
        @endcode
1671  
        @endcode
1672  

1672  

1673  
        @par Complexity
1673  
        @par Complexity
1674  
        Constant.
1674  
        Constant.
1675  

1675  

1676  
        @par Exception Safety
1676  
        @par Exception Safety
1677  
        @li **(1)**, **(2)** no-throw guarantee.
1677  
        @li **(1)**, **(2)** no-throw guarantee.
1678  
        @li **(3)** strong guarantee.
1678  
        @li **(3)** strong guarantee.
1679  

1679  

1680  
        @return The converted number.
1680  
        @return The converted number.
1681  

1681  

1682  
        @param ec Set to the error, if any occurred.
1682  
        @param ec Set to the error, if any occurred.
1683  

1683  

1684  
        @return The converted number.
1684  
        @return The converted number.
1685  

1685  

1686  
        @{
1686  
        @{
1687  
    */
1687  
    */
1688  
    template<class T>
1688  
    template<class T>
1689  
#ifdef BOOST_JSON_DOCS
1689  
#ifdef BOOST_JSON_DOCS
1690  
    T
1690  
    T
1691  
#else
1691  
#else
1692  
    typename std::enable_if<
1692  
    typename std::enable_if<
1693  
        std::is_arithmetic<T>::value &&
1693  
        std::is_arithmetic<T>::value &&
1694  
        ! std::is_same<T, bool>::value,
1694  
        ! std::is_same<T, bool>::value,
1695  
            T>::type
1695  
            T>::type
1696  
#endif
1696  
#endif
1697  
    to_number(system::error_code& ec) const noexcept
1697  
    to_number(system::error_code& ec) const noexcept
1698  
    {
1698  
    {
1699  
        error e;
1699  
        error e;
1700  
        auto result = to_number<T>(e);
1700  
        auto result = to_number<T>(e);
1701  
        BOOST_JSON_FAIL(ec, e);
1701  
        BOOST_JSON_FAIL(ec, e);
1702  
        return result;
1702  
        return result;
1703  
    }
1703  
    }
1704  

1704  

1705  
    template<class T>
1705  
    template<class T>
1706  
#ifdef BOOST_JSON_DOCS
1706  
#ifdef BOOST_JSON_DOCS
1707  
    T
1707  
    T
1708  
#else
1708  
#else
1709  
    typename std::enable_if<
1709  
    typename std::enable_if<
1710  
        std::is_arithmetic<T>::value &&
1710  
        std::is_arithmetic<T>::value &&
1711  
        ! std::is_same<T, bool>::value,
1711  
        ! std::is_same<T, bool>::value,
1712  
            T>::type
1712  
            T>::type
1713  
#endif
1713  
#endif
1714  
    to_number(std::error_code& ec) const noexcept
1714  
    to_number(std::error_code& ec) const noexcept
1715  
    {
1715  
    {
1716  
        system::error_code jec;
1716  
        system::error_code jec;
1717  
        auto result = to_number<T>(jec);
1717  
        auto result = to_number<T>(jec);
1718  
        ec = jec;
1718  
        ec = jec;
1719  
        return result;
1719  
        return result;
1720  
    }
1720  
    }
1721  

1721  

1722  
    /** Overload
1722  
    /** Overload
1723  

1723  

1724  
        @throws boost::system::system_error Overload **(3)** reports errors by
1724  
        @throws boost::system::system_error Overload **(3)** reports errors by
1725  
                throwing an exception.
1725  
                throwing an exception.
1726  
    */
1726  
    */
1727  
    template<class T>
1727  
    template<class T>
1728  
#ifdef BOOST_JSON_DOCS
1728  
#ifdef BOOST_JSON_DOCS
1729  
    T
1729  
    T
1730  
#else
1730  
#else
1731  
    typename std::enable_if<
1731  
    typename std::enable_if<
1732  
        std::is_arithmetic<T>::value &&
1732  
        std::is_arithmetic<T>::value &&
1733  
        ! std::is_same<T, bool>::value,
1733  
        ! std::is_same<T, bool>::value,
1734  
            T>::type
1734  
            T>::type
1735  
#endif
1735  
#endif
1736  
    to_number() const
1736  
    to_number() const
1737  
    {
1737  
    {
1738  
        return try_to_number<T>().value();
1738  
        return try_to_number<T>().value();
1739  
    }
1739  
    }
1740  
    /// @}
1740  
    /// @}
1741  

1741  

1742  
    /** Return the stored number as @ref boost::system::result.
1742  
    /** Return the stored number as @ref boost::system::result.
1743  

1743  

1744  
        This function attempts to return the stored value converted to the
1744  
        This function attempts to return the stored value converted to the
1745  
        arithmetic type `T` which may not be `bool`:
1745  
        arithmetic type `T` which may not be `bool`:
1746  

1746  

1747  
        @li If `T` is an integral type and the stored value is a number which
1747  
        @li If `T` is an integral type and the stored value is a number which
1748  
            can be losslessly converted, the conversion is performed without
1748  
            can be losslessly converted, the conversion is performed without
1749  
            error and `result<T>` containing the converted number is returned.
1749  
            error and `result<T>` containing the converted number is returned.
1750  
        @li If `T` is an integral type and the stored value is a number which
1750  
        @li If `T` is an integral type and the stored value is a number which
1751  
            cannot be losslessly converted, then `result<T>` containing the
1751  
            cannot be losslessly converted, then `result<T>` containing the
1752  
            corresponding `error_code` is returned.
1752  
            corresponding `error_code` is returned.
1753  
        @li If `T` is a floating point type and the stored value is a number,
1753  
        @li If `T` is a floating point type and the stored value is a number,
1754  
            the conversion is performed without error. `result<T>` containing
1754  
            the conversion is performed without error. `result<T>` containing
1755  
            the converted number, with a possible loss of precision, is
1755  
            the converted number, with a possible loss of precision, is
1756  
            returned.
1756  
            returned.
1757  
        @li Otherwise, if the stored value is not a number; that is, if
1757  
        @li Otherwise, if the stored value is not a number; that is, if
1758  
            `this->is_number()` returns `false`, then `result<T>` containing
1758  
            `this->is_number()` returns `false`, then `result<T>` containing
1759  
            the corresponding `error_code` is returned.
1759  
            the corresponding `error_code` is returned.
1760  

1760  

1761  
        @par Constraints
1761  
        @par Constraints
1762  
        @code
1762  
        @code
1763  
        std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1763  
        std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1764  
        @endcode
1764  
        @endcode
1765  

1765  

1766  
        @par Complexity
1766  
        @par Complexity
1767  
        Constant.
1767  
        Constant.
1768  

1768  

1769  
        @par Exception Safety
1769  
        @par Exception Safety
1770  
        No-throw guarantee.
1770  
        No-throw guarantee.
1771  

1771  

1772  
        @return `boost::system::result<T>` with either the converted number or
1772  
        @return `boost::system::result<T>` with either the converted number or
1773  
                an `error_code`.
1773  
                an `error_code`.
1774  
    */
1774  
    */
1775  
    template<class T>
1775  
    template<class T>
1776  
#ifdef BOOST_JSON_DOCS
1776  
#ifdef BOOST_JSON_DOCS
1777  
    system::result<T>
1777  
    system::result<T>
1778  
#else
1778  
#else
1779  
    typename std::enable_if<
1779  
    typename std::enable_if<
1780  
        std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
1780  
        std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
1781  
        system::result<T>
1781  
        system::result<T>
1782  
    >::type
1782  
    >::type
1783  
#endif
1783  
#endif
1784  
    try_to_number() const noexcept
1784  
    try_to_number() const noexcept
1785  
    {
1785  
    {
1786  
        system::error_code ec;
1786  
        system::error_code ec;
1787  
        T result = to_number<T>(ec);
1787  
        T result = to_number<T>(ec);
1788  
        if( ec )
1788  
        if( ec )
1789  
            return {system::in_place_error, ec};
1789  
            return {system::in_place_error, ec};
1790  

1790  

1791  
        return {system::in_place_value, result};
1791  
        return {system::in_place_value, result};
1792  
    }
1792  
    }
1793  

1793  

1794  
    //------------------------------------------------------
1794  
    //------------------------------------------------------
1795  
    //
1795  
    //
1796  
    // Accessors
1796  
    // Accessors
1797  
    //
1797  
    //
1798  
    //------------------------------------------------------
1798  
    //------------------------------------------------------
1799  

1799  

1800  
    /** Return the associated memory resource.
1800  
    /** Return the associated memory resource.
1801  

1801  

1802  
        This function returns a smart pointer to the
1802  
        This function returns a smart pointer to the
1803  
        @ref boost::container::pmr::memory_resource used by the container.
1803  
        @ref boost::container::pmr::memory_resource used by the container.
1804  

1804  

1805  
        @par Complexity
1805  
        @par Complexity
1806  
        Constant.
1806  
        Constant.
1807  

1807  

1808  
        @par Exception Safety
1808  
        @par Exception Safety
1809  
        No-throw guarantee.
1809  
        No-throw guarantee.
1810  
    */
1810  
    */
1811  
    storage_ptr const&
1811  
    storage_ptr const&
1812  
    storage() const noexcept
1812  
    storage() const noexcept
1813  
    {
1813  
    {
1814  
        return sp_;
1814  
        return sp_;
1815  
    }
1815  
    }
1816  

1816  

1817  
    /** Return the associated allocator.
1817  
    /** Return the associated allocator.
1818  

1818  

1819  
        This function returns an instance of @ref allocator_type constructed
1819  
        This function returns an instance of @ref allocator_type constructed
1820  
        from the associated @ref boost::container::pmr::memory_resource.
1820  
        from the associated @ref boost::container::pmr::memory_resource.
1821  

1821  

1822  
        @par Complexity
1822  
        @par Complexity
1823  
        Constant.
1823  
        Constant.
1824  

1824  

1825  
        @par Exception Safety
1825  
        @par Exception Safety
1826  
        No-throw guarantee.
1826  
        No-throw guarantee.
1827  
    */
1827  
    */
1828  
    allocator_type
1828  
    allocator_type
1829  
    get_allocator() const noexcept
1829  
    get_allocator() const noexcept
1830  
    {
1830  
    {
1831  
        return sp_.get();
1831  
        return sp_.get();
1832  
    }
1832  
    }
1833  

1833  

1834  
    //------------------------------------------------------
1834  
    //------------------------------------------------------
1835  

1835  

1836  
    /** Return `result` with a reference to the underlying @ref array
1836  
    /** Return `result` with a reference to the underlying @ref array
1837  

1837  

1838  
        If @ref is_array() is `true`, the result contains a reference to the
1838  
        If @ref is_array() is `true`, the result contains a reference to the
1839  
        underlying @ref array, otherwise it contains an `error_code`.
1839  
        underlying @ref array, otherwise it contains an `error_code`.
1840  

1840  

1841  
        @par Example
1841  
        @par Example
1842  
        The return value can be used in both a boolean context and
1842  
        The return value can be used in both a boolean context and
1843  
        to assign a variable:
1843  
        to assign a variable:
1844  
        @code
1844  
        @code
1845  
        if( auto r = jv.try_as_array() )
1845  
        if( auto r = jv.try_as_array() )
1846  
            return *r;
1846  
            return *r;
1847  
        @endcode
1847  
        @endcode
1848  

1848  

1849  
        But can also be used to throw an exception on error:
1849  
        But can also be used to throw an exception on error:
1850  
        @code
1850  
        @code
1851  
        return jv.try_as_array().value();
1851  
        return jv.try_as_array().value();
1852  
        @endcode
1852  
        @endcode
1853  

1853  

1854  
        @par Complexity
1854  
        @par Complexity
1855  
        Constant.
1855  
        Constant.
1856  

1856  

1857  
        @par Exception Safety
1857  
        @par Exception Safety
1858  
        No-throw guarantee.
1858  
        No-throw guarantee.
1859  

1859  

1860  
        @{
1860  
        @{
1861  
    */
1861  
    */
1862  
    BOOST_JSON_DECL
1862  
    BOOST_JSON_DECL
1863  
    system::result<array&>
1863  
    system::result<array&>
1864  
    try_as_array() noexcept;
1864  
    try_as_array() noexcept;
1865  

1865  

1866  
    BOOST_JSON_DECL
1866  
    BOOST_JSON_DECL
1867  
    system::result<array const&>
1867  
    system::result<array const&>
1868  
    try_as_array() const noexcept;
1868  
    try_as_array() const noexcept;
1869  
    /// @}
1869  
    /// @}
1870  

1870  

1871  
    /** Return `result` with a reference to the underlying @ref object.
1871  
    /** Return `result` with a reference to the underlying @ref object.
1872  

1872  

1873  
        If @ref is_object() is `true`, the result contains a reference to the
1873  
        If @ref is_object() is `true`, the result contains a reference to the
1874  
        underlying @ref object, otherwise it contains an `error_code`.
1874  
        underlying @ref object, otherwise it contains an `error_code`.
1875  

1875  

1876  
        @par Example
1876  
        @par Example
1877  
        The return value can be used in both a boolean context and
1877  
        The return value can be used in both a boolean context and
1878  
        to assign a variable:
1878  
        to assign a variable:
1879  
        @code
1879  
        @code
1880  
        if( auto r = jv.try_as_object() )
1880  
        if( auto r = jv.try_as_object() )
1881  
            return *r;
1881  
            return *r;
1882  
        @endcode
1882  
        @endcode
1883  

1883  

1884  
        But can also be used to throw an exception on error:
1884  
        But can also be used to throw an exception on error:
1885  
        @code
1885  
        @code
1886  
        return jv.try_as_object().value();
1886  
        return jv.try_as_object().value();
1887  
        @endcode
1887  
        @endcode
1888  

1888  

1889  
        @par Complexity
1889  
        @par Complexity
1890  
        Constant.
1890  
        Constant.
1891  

1891  

1892  
        @par Exception Safety
1892  
        @par Exception Safety
1893  
        No-throw guarantee.
1893  
        No-throw guarantee.
1894  

1894  

1895  
        @{
1895  
        @{
1896  
    */
1896  
    */
1897  
    BOOST_JSON_DECL
1897  
    BOOST_JSON_DECL
1898  
    system::result<object&>
1898  
    system::result<object&>
1899  
    try_as_object() noexcept;
1899  
    try_as_object() noexcept;
1900  

1900  

1901  
    BOOST_JSON_DECL
1901  
    BOOST_JSON_DECL
1902  
    system::result<object const&>
1902  
    system::result<object const&>
1903  
    try_as_object() const noexcept;
1903  
    try_as_object() const noexcept;
1904  
    /// @}
1904  
    /// @}
1905  

1905  

1906  
    /** Return `result` with a reference to the underlying @ref string.
1906  
    /** Return `result` with a reference to the underlying @ref string.
1907  

1907  

1908  
        If @ref is_string() is `true`, the result contains a reference to the
1908  
        If @ref is_string() is `true`, the result contains a reference to the
1909  
        underlying @ref string, otherwise it contains an `error_code`.
1909  
        underlying @ref string, otherwise it contains an `error_code`.
1910  

1910  

1911  
        @par Example
1911  
        @par Example
1912  
        The return value can be used in both a boolean context and
1912  
        The return value can be used in both a boolean context and
1913  
        to assign a variable:
1913  
        to assign a variable:
1914  
        @code
1914  
        @code
1915  
        if( auto r = jv.try_as_string() )
1915  
        if( auto r = jv.try_as_string() )
1916  
            return *r;
1916  
            return *r;
1917  
        @endcode
1917  
        @endcode
1918  

1918  

1919  
        But can also be used to throw an exception on error:
1919  
        But can also be used to throw an exception on error:
1920  
        @code
1920  
        @code
1921  
        return jv.try_as_string().value();
1921  
        return jv.try_as_string().value();
1922  
        @endcode
1922  
        @endcode
1923  

1923  

1924  
        @par Complexity
1924  
        @par Complexity
1925  
        Constant.
1925  
        Constant.
1926  

1926  

1927  
        @par Exception Safety
1927  
        @par Exception Safety
1928  
        No-throw guarantee.
1928  
        No-throw guarantee.
1929  

1929  

1930  
        @{
1930  
        @{
1931  
    */
1931  
    */
1932  
    BOOST_JSON_DECL
1932  
    BOOST_JSON_DECL
1933  
    system::result<string&>
1933  
    system::result<string&>
1934  
    try_as_string() noexcept;
1934  
    try_as_string() noexcept;
1935  

1935  

1936  
    BOOST_JSON_DECL
1936  
    BOOST_JSON_DECL
1937  
    system::result<string const&>
1937  
    system::result<string const&>
1938  
    try_as_string() const noexcept;
1938  
    try_as_string() const noexcept;
1939  
    /// @}
1939  
    /// @}
1940  

1940  

1941  
    /** Return `result` with the underlying `std::int64_t`
1941  
    /** Return `result` with the underlying `std::int64_t`
1942  

1942  

1943  
        If @ref is_int64() is `true`, the result contains a reference to **(1)**
1943  
        If @ref is_int64() is `true`, the result contains a reference to **(1)**
1944  
        or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1944  
        or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1945  
        contains an `error_code`.
1945  
        contains an `error_code`.
1946  

1946  

1947  
        @par Example
1947  
        @par Example
1948  
        The return value can be used in both a boolean context and
1948  
        The return value can be used in both a boolean context and
1949  
        to assign a variable:
1949  
        to assign a variable:
1950  
        @code
1950  
        @code
1951  
        if( auto r = jv.try_as_int64() )
1951  
        if( auto r = jv.try_as_int64() )
1952  
            return *r;
1952  
            return *r;
1953  
        @endcode
1953  
        @endcode
1954  

1954  

1955  
        But can also be used to throw an exception on error:
1955  
        But can also be used to throw an exception on error:
1956  
        @code
1956  
        @code
1957  
        return jv.try_as_int64().value();
1957  
        return jv.try_as_int64().value();
1958  
        @endcode
1958  
        @endcode
1959  

1959  

1960  
        @par Complexity
1960  
        @par Complexity
1961  
        Constant.
1961  
        Constant.
1962  

1962  

1963  
        @par Exception Safety
1963  
        @par Exception Safety
1964  
        No-throw guarantee.
1964  
        No-throw guarantee.
1965  

1965  

1966  
        @{
1966  
        @{
1967  
    */
1967  
    */
1968  
    BOOST_JSON_DECL
1968  
    BOOST_JSON_DECL
1969  
    system::result<std::int64_t&>
1969  
    system::result<std::int64_t&>
1970  
    try_as_int64() noexcept;
1970  
    try_as_int64() noexcept;
1971  

1971  

1972  
    BOOST_JSON_DECL
1972  
    BOOST_JSON_DECL
1973  
    system::result<std::int64_t>
1973  
    system::result<std::int64_t>
1974  
    try_as_int64() const noexcept;
1974  
    try_as_int64() const noexcept;
1975  
    /// @}
1975  
    /// @}
1976  

1976  

1977  
    /** Return `result` with the underlying `std::uint64_t`.
1977  
    /** Return `result` with the underlying `std::uint64_t`.
1978  

1978  

1979  
        If @ref is_uint64() is `true`, the result contains a reference to **(1)**
1979  
        If @ref is_uint64() is `true`, the result contains a reference to **(1)**
1980  
        or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1980  
        or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1981  
        contains an `error_code`.
1981  
        contains an `error_code`.
1982  

1982  

1983  
        @par Example
1983  
        @par Example
1984  
        The return value can be used in both a boolean context and
1984  
        The return value can be used in both a boolean context and
1985  
        to assign a variable:
1985  
        to assign a variable:
1986  
        @code
1986  
        @code
1987  
        if( auto r = jv.try_as_uint64() )
1987  
        if( auto r = jv.try_as_uint64() )
1988  
            return *r;
1988  
            return *r;
1989  
        @endcode
1989  
        @endcode
1990  

1990  

1991  
        But can also be used to throw an exception on error:
1991  
        But can also be used to throw an exception on error:
1992  
        @code
1992  
        @code
1993  
        return jv.try_as_uint64().value();
1993  
        return jv.try_as_uint64().value();
1994  
        @endcode
1994  
        @endcode
1995  

1995  

1996  
        @par Complexity
1996  
        @par Complexity
1997  
        Constant.
1997  
        Constant.
1998  

1998  

1999  
        @par Exception Safety
1999  
        @par Exception Safety
2000  
        No-throw guarantee.
2000  
        No-throw guarantee.
2001  

2001  

2002  
        @{
2002  
        @{
2003  
    */
2003  
    */
2004  
    BOOST_JSON_DECL
2004  
    BOOST_JSON_DECL
2005  
    system::result<std::uint64_t&>
2005  
    system::result<std::uint64_t&>
2006  
    try_as_uint64() noexcept;
2006  
    try_as_uint64() noexcept;
2007  

2007  

2008  
    BOOST_JSON_DECL
2008  
    BOOST_JSON_DECL
2009  
    system::result<std::uint64_t>
2009  
    system::result<std::uint64_t>
2010  
    try_as_uint64() const noexcept;
2010  
    try_as_uint64() const noexcept;
2011  
    /// @}
2011  
    /// @}
2012  

2012  

2013  
    /** Return `result` with the underlying `double`
2013  
    /** Return `result` with the underlying `double`
2014  

2014  

2015  
        If @ref is_double() is `true`, the result contains a reference to **(1)**
2015  
        If @ref is_double() is `true`, the result contains a reference to **(1)**
2016  
        or a copy of **(2)** the underlying `double`, otherwise it
2016  
        or a copy of **(2)** the underlying `double`, otherwise it
2017  
        contains an `error_code`.
2017  
        contains an `error_code`.
2018  

2018  

2019  
        @par Example
2019  
        @par Example
2020  
        The return value can be used in both a boolean context and
2020  
        The return value can be used in both a boolean context and
2021  
        to assign a variable:
2021  
        to assign a variable:
2022  
        @code
2022  
        @code
2023  
        if( auto r = jv.try_as_double() )
2023  
        if( auto r = jv.try_as_double() )
2024  
            return *r;
2024  
            return *r;
2025  
        @endcode
2025  
        @endcode
2026  

2026  

2027  
        But can also be used to throw an exception on error:
2027  
        But can also be used to throw an exception on error:
2028  
        @code
2028  
        @code
2029  
        return jv.try_as_double().value();
2029  
        return jv.try_as_double().value();
2030  
        @endcode
2030  
        @endcode
2031  

2031  

2032  
        @par Complexity
2032  
        @par Complexity
2033  
        Constant.
2033  
        Constant.
2034  

2034  

2035  
        @par Exception Safety
2035  
        @par Exception Safety
2036  
        No-throw guarantee.
2036  
        No-throw guarantee.
2037  

2037  

2038  
        @{
2038  
        @{
2039  
    */
2039  
    */
2040  
    BOOST_JSON_DECL
2040  
    BOOST_JSON_DECL
2041  
    system::result<double&>
2041  
    system::result<double&>
2042  
    try_as_double() noexcept;
2042  
    try_as_double() noexcept;
2043  

2043  

2044  
    BOOST_JSON_DECL
2044  
    BOOST_JSON_DECL
2045  
    system::result<double>
2045  
    system::result<double>
2046  
    try_as_double() const noexcept;
2046  
    try_as_double() const noexcept;
2047  
    /// @}
2047  
    /// @}
2048  

2048  

2049  
    /** Return `result` with the underlying `bool`
2049  
    /** Return `result` with the underlying `bool`
2050  

2050  

2051  
        If @ref is_bool() is `true`, the result contains a reference to **(1)**
2051  
        If @ref is_bool() is `true`, the result contains a reference to **(1)**
2052  
        or a copy to **(2)** the underlying `bool`, otherwise it contains an
2052  
        or a copy to **(2)** the underlying `bool`, otherwise it contains an
2053  
        `error_code`.
2053  
        `error_code`.
2054  

2054  

2055  
        @par Example
2055  
        @par Example
2056  
        The return value can be used in both a boolean context and
2056  
        The return value can be used in both a boolean context and
2057  
        to assign a variable:
2057  
        to assign a variable:
2058  
        @code
2058  
        @code
2059  
        if( auto r = jv.try_as_bool() )
2059  
        if( auto r = jv.try_as_bool() )
2060  
            return *r;
2060  
            return *r;
2061  
        @endcode
2061  
        @endcode
2062  

2062  

2063  
        But can also be used to throw an exception on error:
2063  
        But can also be used to throw an exception on error:
2064  
        @code
2064  
        @code
2065  
        return jv.try_as_bool().value();
2065  
        return jv.try_as_bool().value();
2066  
        @endcode
2066  
        @endcode
2067  

2067  

2068  
        @par Complexity
2068  
        @par Complexity
2069  
        Constant.
2069  
        Constant.
2070  

2070  

2071  
        @par Exception Safety
2071  
        @par Exception Safety
2072  
        No-throw guarantee.
2072  
        No-throw guarantee.
2073  

2073  

2074  
        @{
2074  
        @{
2075  
    */
2075  
    */
2076  
    BOOST_JSON_DECL
2076  
    BOOST_JSON_DECL
2077  
    system::result<bool&>
2077  
    system::result<bool&>
2078  
    try_as_bool() noexcept;
2078  
    try_as_bool() noexcept;
2079  

2079  

2080  
    BOOST_JSON_DECL
2080  
    BOOST_JSON_DECL
2081  
    system::result<bool>
2081  
    system::result<bool>
2082  
    try_as_bool() const noexcept;
2082  
    try_as_bool() const noexcept;
2083  
    /// @}
2083  
    /// @}
2084  

2084  

2085  
    /** Return engaged `result` if the `value` is null.
2085  
    /** Return engaged `result` if the `value` is null.
2086  

2086  

2087  
        If @ref is_null() is `true`, the result is engaged, otherwise it
2087  
        If @ref is_null() is `true`, the result is engaged, otherwise it
2088  
        contains an `error_code`.
2088  
        contains an `error_code`.
2089  

2089  

2090  
        @par Example
2090  
        @par Example
2091  
        The return value can be used in both a boolean context and
2091  
        The return value can be used in both a boolean context and
2092  
        to assign a variable:
2092  
        to assign a variable:
2093  
        @code
2093  
        @code
2094  
        if( auto r = jv.try_as_null() )
2094  
        if( auto r = jv.try_as_null() )
2095  
            return *r;
2095  
            return *r;
2096  
        @endcode
2096  
        @endcode
2097  

2097  

2098  
        But can also be used to throw an exception on error:
2098  
        But can also be used to throw an exception on error:
2099  
        @code
2099  
        @code
2100  
        return jv.try_as_null().value();
2100  
        return jv.try_as_null().value();
2101  
        @endcode
2101  
        @endcode
2102  

2102  

2103  
        @par Complexity
2103  
        @par Complexity
2104  
        Constant.
2104  
        Constant.
2105  

2105  

2106  
        @par Exception Safety
2106  
        @par Exception Safety
2107  
        No-throw guarantee.
2107  
        No-throw guarantee.
2108  
    */
2108  
    */
2109  
    BOOST_JSON_DECL
2109  
    BOOST_JSON_DECL
2110  
    system::result<std::nullptr_t>
2110  
    system::result<std::nullptr_t>
2111  
    try_as_null() const noexcept;
2111  
    try_as_null() const noexcept;
2112  

2112  

2113  
    //------------------------------------------------------
2113  
    //------------------------------------------------------
2114  

2114  

2115  
    /** Return the underlying @ref object, or throw an exception.
2115  
    /** Return the underlying @ref object, or throw an exception.
2116  

2116  

2117  
        If @ref is_object() is `true`, returns a reference to the underlying
2117  
        If @ref is_object() is `true`, returns a reference to the underlying
2118  
        @ref object, otherwise throws an exception.
2118  
        @ref object, otherwise throws an exception.
2119  

2119  

2120  
        @par Exception Safety
2120  
        @par Exception Safety
2121  
        Strong guarantee.
2121  
        Strong guarantee.
2122  

2122  

2123  
        @throw boost::system::system_error `! this->is_object()`.
2123  
        @throw boost::system::system_error `! this->is_object()`.
2124  

2124  

2125  
        @param loc @ref boost::source_location to use in thrown exception; the
2125  
        @param loc @ref boost::source_location to use in thrown exception; the
2126  
               source location of the call site by default.
2126  
               source location of the call site by default.
2127  

2127  

2128  
        @par Complexity
2128  
        @par Complexity
2129  
        Constant.
2129  
        Constant.
2130  

2130  

2131  
        @{
2131  
        @{
2132  
    */
2132  
    */
2133  
    object&
2133  
    object&
2134  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2134  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2135  
    {
2135  
    {
2136  
        auto& self = const_cast<value const&>(*this);
2136  
        auto& self = const_cast<value const&>(*this);
2137  
        return const_cast<object&>( self.as_object(loc) );
2137  
        return const_cast<object&>( self.as_object(loc) );
2138  
    }
2138  
    }
2139  

2139  

2140  
    /// Overload
2140  
    /// Overload
2141  
    object&&
2141  
    object&&
2142  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2142  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2143  
    {
2143  
    {
2144  
        return std::move( as_object(loc) );
2144  
        return std::move( as_object(loc) );
2145  
    }
2145  
    }
2146  

2146  

2147  
    /// Overload
2147  
    /// Overload
2148  
    BOOST_JSON_DECL
2148  
    BOOST_JSON_DECL
2149  
    object const&
2149  
    object const&
2150  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2150  
    as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2151  
    /// @}
2151  
    /// @}
2152  

2152  

2153  
    /** Return the underlying @ref array, or throw an exception.
2153  
    /** Return the underlying @ref array, or throw an exception.
2154  

2154  

2155  
        If @ref is_array() is `true`, returns a reference to the underlying
2155  
        If @ref is_array() is `true`, returns a reference to the underlying
2156  
        @ref array, otherwise throws an exception.
2156  
        @ref array, otherwise throws an exception.
2157  

2157  

2158  
        @par Exception Safety
2158  
        @par Exception Safety
2159  
        Strong guarantee.
2159  
        Strong guarantee.
2160  

2160  

2161  
        @throw boost::system::system_error `! this->is_array()`.
2161  
        @throw boost::system::system_error `! this->is_array()`.
2162  

2162  

2163  
        @param loc @ref boost::source_location to use in thrown exception; the
2163  
        @param loc @ref boost::source_location to use in thrown exception; the
2164  
               source location of the call site by default.
2164  
               source location of the call site by default.
2165  

2165  

2166  
        @par Complexity
2166  
        @par Complexity
2167  
        Constant.
2167  
        Constant.
2168  

2168  

2169  
        @{
2169  
        @{
2170  
    */
2170  
    */
2171  
    array&
2171  
    array&
2172  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2172  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2173  
    {
2173  
    {
2174  
        auto& self = const_cast<value const&>(*this);
2174  
        auto& self = const_cast<value const&>(*this);
2175  
        return const_cast<array&>( self.as_array(loc) );
2175  
        return const_cast<array&>( self.as_array(loc) );
2176  
    }
2176  
    }
2177  

2177  

2178  
    /// Overload
2178  
    /// Overload
2179  
    array&&
2179  
    array&&
2180  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2180  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2181  
    {
2181  
    {
2182  
        return std::move( as_array(loc) );
2182  
        return std::move( as_array(loc) );
2183  
    }
2183  
    }
2184  

2184  

2185  
    /// Overload
2185  
    /// Overload
2186  
    BOOST_JSON_DECL
2186  
    BOOST_JSON_DECL
2187  
    array const&
2187  
    array const&
2188  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2188  
    as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2189  
    /// @}
2189  
    /// @}
2190  

2190  

2191  
    /** Return the underlying @ref string, or throw an exception.
2191  
    /** Return the underlying @ref string, or throw an exception.
2192  

2192  

2193  
        If @ref is_string() is `true`, returns a reference to the underlying
2193  
        If @ref is_string() is `true`, returns a reference to the underlying
2194  
        @ref string, otherwise throws an exception.
2194  
        @ref string, otherwise throws an exception.
2195  

2195  

2196  
        @par Exception Safety
2196  
        @par Exception Safety
2197  
        Strong guarantee.
2197  
        Strong guarantee.
2198  

2198  

2199  
        @throw boost::system::system_error `! this->is_string()`.
2199  
        @throw boost::system::system_error `! this->is_string()`.
2200  

2200  

2201  
        @param loc @ref boost::source_location to use in thrown exception; the
2201  
        @param loc @ref boost::source_location to use in thrown exception; the
2202  
               source location of the call site by default.
2202  
               source location of the call site by default.
2203  

2203  

2204  
        @par Complexity
2204  
        @par Complexity
2205  
        Constant.
2205  
        Constant.
2206  

2206  

2207  
        @{
2207  
        @{
2208  
    */
2208  
    */
2209  
    string&
2209  
    string&
2210  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2210  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2211  
    {
2211  
    {
2212  
        auto& self = const_cast<value const&>(*this);
2212  
        auto& self = const_cast<value const&>(*this);
2213  
        return const_cast<string&>( self.as_string(loc) );
2213  
        return const_cast<string&>( self.as_string(loc) );
2214  
    }
2214  
    }
2215  

2215  

2216  
    /// Overload
2216  
    /// Overload
2217  
    string&&
2217  
    string&&
2218  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2218  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2219  
    {
2219  
    {
2220  
        return std::move( as_string(loc) );
2220  
        return std::move( as_string(loc) );
2221  
    }
2221  
    }
2222  

2222  

2223  
    /// Overload
2223  
    /// Overload
2224  
    BOOST_JSON_DECL
2224  
    BOOST_JSON_DECL
2225  
    string const&
2225  
    string const&
2226  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2226  
    as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2227  
    /// @}
2227  
    /// @}
2228  

2228  

2229  
    /** Return the underlying `std::int64_t`, or throw an exception.
2229  
    /** Return the underlying `std::int64_t`, or throw an exception.
2230  

2230  

2231  
        If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
2231  
        If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
2232  
        of **(2)** the underlying `std::int64_t`, otherwise throws an
2232  
        of **(2)** the underlying `std::int64_t`, otherwise throws an
2233  
        exception.
2233  
        exception.
2234  

2234  

2235  
        @note This function is the intended for direct access to the underlying
2235  
        @note This function is the intended for direct access to the underlying
2236  
        object, __if__ it has the type `std::int64_t`. It does not convert the
2236  
        object, __if__ it has the type `std::int64_t`. It does not convert the
2237  
        underlying object to the type `std::int64_t` even if a lossless
2237  
        underlying object to the type `std::int64_t` even if a lossless
2238  
        conversion is possible. If you are not sure which kind your `value`
2238  
        conversion is possible. If you are not sure which kind your `value`
2239  
        has, and you only care about getting a `std::int64_t` number, consider
2239  
        has, and you only care about getting a `std::int64_t` number, consider
2240  
        using @ref to_number instead.
2240  
        using @ref to_number instead.
2241  

2241  

2242  
        @par Exception Safety
2242  
        @par Exception Safety
2243  
        Strong guarantee.
2243  
        Strong guarantee.
2244  

2244  

2245  
        @throw boost::system::system_error `! this->is_int64()`.
2245  
        @throw boost::system::system_error `! this->is_int64()`.
2246  

2246  

2247  
        @param loc @ref boost::source_location to use in thrown exception; the
2247  
        @param loc @ref boost::source_location to use in thrown exception; the
2248  
               source location of the call site by default.
2248  
               source location of the call site by default.
2249  

2249  

2250  
        @par Complexity
2250  
        @par Complexity
2251  
        Constant.
2251  
        Constant.
2252  

2252  

2253  
        @{
2253  
        @{
2254  
    */
2254  
    */
2255  
    BOOST_JSON_DECL
2255  
    BOOST_JSON_DECL
2256  
    std::int64_t&
2256  
    std::int64_t&
2257  
    as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
2257  
    as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
2258  

2258  

2259  
    /// Overload
2259  
    /// Overload
2260  
    BOOST_JSON_DECL
2260  
    BOOST_JSON_DECL
2261  
    std::int64_t
2261  
    std::int64_t
2262  
    as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2262  
    as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2263  
    /// @}
2263  
    /// @}
2264  

2264  

2265  
    /** Return the underlying `std::uint64_t`, or throw an exception.
2265  
    /** Return the underlying `std::uint64_t`, or throw an exception.
2266  

2266  

2267  
        If @ref is_uint64() is `true`, returns a reference to **(1)** or a
2267  
        If @ref is_uint64() is `true`, returns a reference to **(1)** or a
2268  
        copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2268  
        copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2269  
        exception.
2269  
        exception.
2270  

2270  

2271  
        @note This function is intended for direct access to the underlying
2271  
        @note This function is intended for direct access to the underlying
2272  
        object, __if__ it has the type `std::uint64_t`. It does not convert the
2272  
        object, __if__ it has the type `std::uint64_t`. It does not convert the
2273  
        underlying object to the type `std::uint64_t` even if a lossless
2273  
        underlying object to the type `std::uint64_t` even if a lossless
2274  
        conversion is possible. If you are not sure which kind your `value`
2274  
        conversion is possible. If you are not sure which kind your `value`
2275  
        has, and you only care about getting a `std::uint64_t` number, consider
2275  
        has, and you only care about getting a `std::uint64_t` number, consider
2276  
        using @ref to_number instead.
2276  
        using @ref to_number instead.
2277  

2277  

2278  
        @par Exception Safety
2278  
        @par Exception Safety
2279  
        Strong guarantee.
2279  
        Strong guarantee.
2280  

2280  

2281  
        @throw boost::system::system_error `! this->is_uint64()`.
2281  
        @throw boost::system::system_error `! this->is_uint64()`.
2282  

2282  

2283  
        @param loc @ref boost::source_location to use in thrown exception; the
2283  
        @param loc @ref boost::source_location to use in thrown exception; the
2284  
               source location of the call site by default.
2284  
               source location of the call site by default.
2285  

2285  

2286  
        @par Complexity
2286  
        @par Complexity
2287  
        Constant.
2287  
        Constant.
2288  

2288  

2289  
        @{
2289  
        @{
2290  
    */
2290  
    */
2291  
    BOOST_JSON_DECL
2291  
    BOOST_JSON_DECL
2292  
    std::uint64_t&
2292  
    std::uint64_t&
2293  
    as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
2293  
    as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
2294  

2294  

2295  
    /// Overload
2295  
    /// Overload
2296  
    BOOST_JSON_DECL
2296  
    BOOST_JSON_DECL
2297  
    std::uint64_t
2297  
    std::uint64_t
2298  
    as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2298  
    as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2299  
    /// @}
2299  
    /// @}
2300  

2300  

2301  
    /** Return the underlying `double`, or throw an exception.
2301  
    /** Return the underlying `double`, or throw an exception.
2302  

2302  

2303  
        If @ref is_double() is `true`, returns a reference to **(1)** or a copy
2303  
        If @ref is_double() is `true`, returns a reference to **(1)** or a copy
2304  
        of **(2)** the underlying `double`, otherwise throws an exception.
2304  
        of **(2)** the underlying `double`, otherwise throws an exception.
2305  

2305  

2306  
        @note This function is intended for direct access to the underlying
2306  
        @note This function is intended for direct access to the underlying
2307  
        object, __if__ it has the type `double`. It does not convert the
2307  
        object, __if__ it has the type `double`. It does not convert the
2308  
        underlying object to type `double` even if a lossless conversion is
2308  
        underlying object to type `double` even if a lossless conversion is
2309  
        possible. If you are not sure which kind your `value` has, and you only
2309  
        possible. If you are not sure which kind your `value` has, and you only
2310  
        care about getting a `double` number, consider using @ref to_number
2310  
        care about getting a `double` number, consider using @ref to_number
2311  
        instead.
2311  
        instead.
2312  

2312  

2313  
        @par Exception Safety
2313  
        @par Exception Safety
2314  
        Strong guarantee.
2314  
        Strong guarantee.
2315  

2315  

2316  
        @throw boost::system::system_error `! this->is_double()`.
2316  
        @throw boost::system::system_error `! this->is_double()`.
2317  

2317  

2318  
        @param loc @ref boost::source_location to use in thrown exception; the
2318  
        @param loc @ref boost::source_location to use in thrown exception; the
2319  
               source location of the call site by default.
2319  
               source location of the call site by default.
2320  

2320  

2321  
        @par Complexity
2321  
        @par Complexity
2322  
        Constant.
2322  
        Constant.
2323  

2323  

2324  
        @{
2324  
        @{
2325  
    */
2325  
    */
2326  
    BOOST_JSON_DECL
2326  
    BOOST_JSON_DECL
2327  
    double&
2327  
    double&
2328  
    as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
2328  
    as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
2329  

2329  

2330  
    /// Overload
2330  
    /// Overload
2331  
    BOOST_JSON_DECL
2331  
    BOOST_JSON_DECL
2332  
    double
2332  
    double
2333  
    as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2333  
    as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2334  
    /// @}
2334  
    /// @}
2335  

2335  

2336  
    /** Return the underlying `bool`, or throw an exception.
2336  
    /** Return the underlying `bool`, or throw an exception.
2337  

2337  

2338  
        If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
2338  
        If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
2339  
        of **(2)** the underlying `bool`, otherwise throws an exception.
2339  
        of **(2)** the underlying `bool`, otherwise throws an exception.
2340  

2340  

2341  
        @par Exception Safety
2341  
        @par Exception Safety
2342  
        Strong guarantee.
2342  
        Strong guarantee.
2343  

2343  

2344  
        @throw boost::system::system_error `! this->is_bool()`.
2344  
        @throw boost::system::system_error `! this->is_bool()`.
2345  

2345  

2346  
        @param loc @ref boost::source_location to use in thrown exception; the
2346  
        @param loc @ref boost::source_location to use in thrown exception; the
2347  
               source location of the call site by default.
2347  
               source location of the call site by default.
2348  

2348  

2349  
        @par Complexity
2349  
        @par Complexity
2350  
        Constant.
2350  
        Constant.
2351  

2351  

2352  
        @{
2352  
        @{
2353  
    */
2353  
    */
2354  
    BOOST_JSON_DECL
2354  
    BOOST_JSON_DECL
2355  
    bool&
2355  
    bool&
2356  
    as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
2356  
    as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
2357  

2357  

2358  
    /// Overload
2358  
    /// Overload
2359  
    BOOST_JSON_DECL
2359  
    BOOST_JSON_DECL
2360  
    bool
2360  
    bool
2361  
    as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2361  
    as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2362  
    /// @}
2362  
    /// @}
2363  

2363  

2364  
    //------------------------------------------------------
2364  
    //------------------------------------------------------
2365  

2365  

2366  
    /** Return the underlying @ref object, without checking.
2366  
    /** Return the underlying @ref object, without checking.
2367  

2367  

2368  
        This is the fastest way to access the underlying representation when
2368  
        This is the fastest way to access the underlying representation when
2369  
        the kind is known in advance.
2369  
        the kind is known in advance.
2370  

2370  

2371  
        @par Preconditions
2371  
        @par Preconditions
2372  

2372  

2373  
        @code
2373  
        @code
2374  
        this->is_object()
2374  
        this->is_object()
2375  
        @endcode
2375  
        @endcode
2376  

2376  

2377  
        @par Complexity
2377  
        @par Complexity
2378  
        Constant.
2378  
        Constant.
2379  

2379  

2380  
        @par Exception Safety
2380  
        @par Exception Safety
2381  
        No-throw guarantee.
2381  
        No-throw guarantee.
2382  

2382  

2383  
        @{
2383  
        @{
2384  
    */
2384  
    */
2385  
    object&
2385  
    object&
2386  
    get_object() & noexcept
2386  
    get_object() & noexcept
2387  
    {
2387  
    {
2388  
        BOOST_ASSERT(is_object());
2388  
        BOOST_ASSERT(is_object());
2389  
        return obj_;
2389  
        return obj_;
2390  
    }
2390  
    }
2391  

2391  

2392  
    object&&
2392  
    object&&
2393  
    get_object() && noexcept
2393  
    get_object() && noexcept
2394  
    {
2394  
    {
2395  
        BOOST_ASSERT(is_object());
2395  
        BOOST_ASSERT(is_object());
2396  
        return std::move(obj_);
2396  
        return std::move(obj_);
2397  
    }
2397  
    }
2398  

2398  

2399  
    object const&
2399  
    object const&
2400  
    get_object() const& noexcept
2400  
    get_object() const& noexcept
2401  
    {
2401  
    {
2402  
        BOOST_ASSERT(is_object());
2402  
        BOOST_ASSERT(is_object());
2403  
        return obj_;
2403  
        return obj_;
2404  
    }
2404  
    }
2405  
    /// @}
2405  
    /// @}
2406  

2406  

2407  
    /** Return the underlying @ref array, without checking.
2407  
    /** Return the underlying @ref array, without checking.
2408  

2408  

2409  
        This is the fastest way to access the underlying representation when
2409  
        This is the fastest way to access the underlying representation when
2410  
        the kind is known in advance.
2410  
        the kind is known in advance.
2411  

2411  

2412  
        @par Preconditions
2412  
        @par Preconditions
2413  

2413  

2414  
        @code
2414  
        @code
2415  
        this->is_array()
2415  
        this->is_array()
2416  
        @endcode
2416  
        @endcode
2417  

2417  

2418  
        @par Complexity
2418  
        @par Complexity
2419  
        Constant.
2419  
        Constant.
2420  

2420  

2421  
        @par Exception Safety
2421  
        @par Exception Safety
2422  
        No-throw guarantee.
2422  
        No-throw guarantee.
2423  

2423  

2424  
        @{
2424  
        @{
2425  
    */
2425  
    */
2426  
    array&
2426  
    array&
2427  
    get_array() & noexcept
2427  
    get_array() & noexcept
2428  
    {
2428  
    {
2429  
        BOOST_ASSERT(is_array());
2429  
        BOOST_ASSERT(is_array());
2430  
        return arr_;
2430  
        return arr_;
2431  
    }
2431  
    }
2432  

2432  

2433  
    array&&
2433  
    array&&
2434  
    get_array() && noexcept
2434  
    get_array() && noexcept
2435  
    {
2435  
    {
2436  
        BOOST_ASSERT(is_array());
2436  
        BOOST_ASSERT(is_array());
2437  
        return std::move(arr_);
2437  
        return std::move(arr_);
2438  
    }
2438  
    }
2439  

2439  

2440  
    array const&
2440  
    array const&
2441  
    get_array() const& noexcept
2441  
    get_array() const& noexcept
2442  
    {
2442  
    {
2443  
        BOOST_ASSERT(is_array());
2443  
        BOOST_ASSERT(is_array());
2444  
        return arr_;
2444  
        return arr_;
2445  
    }
2445  
    }
2446  
    /// @}
2446  
    /// @}
2447  

2447  

2448  
    /** Return the underlying @ref string, without checking.
2448  
    /** Return the underlying @ref string, without checking.
2449  

2449  

2450  
        This is the fastest way to access the underlying representation when
2450  
        This is the fastest way to access the underlying representation when
2451  
        the kind is known in advance.
2451  
        the kind is known in advance.
2452  

2452  

2453  
        @par Preconditions
2453  
        @par Preconditions
2454  

2454  

2455  
        @code
2455  
        @code
2456  
        this->is_string()
2456  
        this->is_string()
2457  
        @endcode
2457  
        @endcode
2458  

2458  

2459  
        @par Complexity
2459  
        @par Complexity
2460  
        Constant.
2460  
        Constant.
2461  

2461  

2462  
        @par Exception Safety
2462  
        @par Exception Safety
2463  
        No-throw guarantee.
2463  
        No-throw guarantee.
2464  

2464  

2465  
        @{
2465  
        @{
2466  
    */
2466  
    */
2467  
    string&
2467  
    string&
2468  
    get_string() & noexcept
2468  
    get_string() & noexcept
2469  
    {
2469  
    {
2470  
        BOOST_ASSERT(is_string());
2470  
        BOOST_ASSERT(is_string());
2471  
        return str_;
2471  
        return str_;
2472  
    }
2472  
    }
2473  

2473  

2474  
    string&&
2474  
    string&&
2475  
    get_string() && noexcept
2475  
    get_string() && noexcept
2476  
    {
2476  
    {
2477  
        BOOST_ASSERT(is_string());
2477  
        BOOST_ASSERT(is_string());
2478  
        return std::move(str_);
2478  
        return std::move(str_);
2479  
    }
2479  
    }
2480  

2480  

2481  
    string const&
2481  
    string const&
2482  
    get_string() const& noexcept
2482  
    get_string() const& noexcept
2483  
    {
2483  
    {
2484  
        BOOST_ASSERT(is_string());
2484  
        BOOST_ASSERT(is_string());
2485  
        return str_;
2485  
        return str_;
2486  
    }
2486  
    }
2487  
    /// @}
2487  
    /// @}
2488  

2488  

2489  
    /** Return the underlying `std::int64_t`, without checking.
2489  
    /** Return the underlying `std::int64_t`, without checking.
2490  

2490  

2491  
        This is the fastest way to access the underlying representation when
2491  
        This is the fastest way to access the underlying representation when
2492  
        the kind is known in advance.
2492  
        the kind is known in advance.
2493  

2493  

2494  
        @par Preconditions
2494  
        @par Preconditions
2495  

2495  

2496  
        @code
2496  
        @code
2497  
        this->is_int64()
2497  
        this->is_int64()
2498  
        @endcode
2498  
        @endcode
2499  

2499  

2500  
        @par Complexity
2500  
        @par Complexity
2501  
        Constant.
2501  
        Constant.
2502  

2502  

2503  
        @par Exception Safety
2503  
        @par Exception Safety
2504  
        No-throw guarantee.
2504  
        No-throw guarantee.
2505  

2505  

2506  
        @{
2506  
        @{
2507  
    */
2507  
    */
2508  
    std::int64_t&
2508  
    std::int64_t&
2509  
    get_int64() noexcept
2509  
    get_int64() noexcept
2510  
    {
2510  
    {
2511  
        BOOST_ASSERT(is_int64());
2511  
        BOOST_ASSERT(is_int64());
2512  
        return sca_.i;
2512  
        return sca_.i;
2513  
    }
2513  
    }
2514  

2514  

2515  
    std::int64_t
2515  
    std::int64_t
2516  
    get_int64() const noexcept
2516  
    get_int64() const noexcept
2517  
    {
2517  
    {
2518  
        BOOST_ASSERT(is_int64());
2518  
        BOOST_ASSERT(is_int64());
2519  
        return sca_.i;
2519  
        return sca_.i;
2520  
    }
2520  
    }
2521  
    /// @}
2521  
    /// @}
2522  

2522  

2523  
    /** Return the underlying `std::uint64_t`, without checking.
2523  
    /** Return the underlying `std::uint64_t`, without checking.
2524  

2524  

2525  
        This is the fastest way to access the underlying representation when
2525  
        This is the fastest way to access the underlying representation when
2526  
        the kind is known in advance.
2526  
        the kind is known in advance.
2527  

2527  

2528  
        @par Preconditions
2528  
        @par Preconditions
2529  

2529  

2530  
        @code
2530  
        @code
2531  
        this->is_uint64()
2531  
        this->is_uint64()
2532  
        @endcode
2532  
        @endcode
2533  

2533  

2534  
        @par Complexity
2534  
        @par Complexity
2535  
        Constant.
2535  
        Constant.
2536  

2536  

2537  
        @par Exception Safety
2537  
        @par Exception Safety
2538  
        No-throw guarantee.
2538  
        No-throw guarantee.
2539  

2539  

2540  
        @{
2540  
        @{
2541  
    */
2541  
    */
2542  
    std::uint64_t&
2542  
    std::uint64_t&
2543  
    get_uint64() noexcept
2543  
    get_uint64() noexcept
2544  
    {
2544  
    {
2545  
        BOOST_ASSERT(is_uint64());
2545  
        BOOST_ASSERT(is_uint64());
2546  
        return sca_.u;
2546  
        return sca_.u;
2547  
    }
2547  
    }
2548  

2548  

2549  
    std::uint64_t
2549  
    std::uint64_t
2550  
    get_uint64() const noexcept
2550  
    get_uint64() const noexcept
2551  
    {
2551  
    {
2552  
        BOOST_ASSERT(is_uint64());
2552  
        BOOST_ASSERT(is_uint64());
2553  
        return sca_.u;
2553  
        return sca_.u;
2554  
    }
2554  
    }
2555  
    /// @}
2555  
    /// @}
2556  

2556  

2557  
    /** Return the underlying `double`, without checking.
2557  
    /** Return the underlying `double`, without checking.
2558  

2558  

2559  
        This is the fastest way to access the underlying
2559  
        This is the fastest way to access the underlying
2560  
        representation when the kind is known in advance.
2560  
        representation when the kind is known in advance.
2561  

2561  

2562  
        @par Preconditions
2562  
        @par Preconditions
2563  

2563  

2564  
        @code
2564  
        @code
2565  
        this->is_double()
2565  
        this->is_double()
2566  
        @endcode
2566  
        @endcode
2567  

2567  

2568  
        @par Complexity
2568  
        @par Complexity
2569  
        Constant.
2569  
        Constant.
2570  

2570  

2571  
        @par Exception Safety
2571  
        @par Exception Safety
2572  
        No-throw guarantee.
2572  
        No-throw guarantee.
2573  

2573  

2574  
        @{
2574  
        @{
2575  
    */
2575  
    */
2576  
    double&
2576  
    double&
2577  
    get_double() noexcept
2577  
    get_double() noexcept
2578  
    {
2578  
    {
2579  
        BOOST_ASSERT(is_double());
2579  
        BOOST_ASSERT(is_double());
2580  
        return sca_.d;
2580  
        return sca_.d;
2581  
    }
2581  
    }
2582  

2582  

2583  
    double
2583  
    double
2584  
    get_double() const noexcept
2584  
    get_double() const noexcept
2585  
    {
2585  
    {
2586  
        BOOST_ASSERT(is_double());
2586  
        BOOST_ASSERT(is_double());
2587  
        return sca_.d;
2587  
        return sca_.d;
2588  
    }
2588  
    }
2589  
    /// @}
2589  
    /// @}
2590  

2590  

2591  
    /** Return the underlying `bool`, without checking.
2591  
    /** Return the underlying `bool`, without checking.
2592  

2592  

2593  
        This is the fastest way to access the underlying representation when
2593  
        This is the fastest way to access the underlying representation when
2594  
        the kind is known in advance.
2594  
        the kind is known in advance.
2595  

2595  

2596  
        @par Preconditions
2596  
        @par Preconditions
2597  

2597  

2598  
        @code
2598  
        @code
2599  
        this->is_bool()
2599  
        this->is_bool()
2600  
        @endcode
2600  
        @endcode
2601  

2601  

2602  
        @par Complexity
2602  
        @par Complexity
2603  
        Constant.
2603  
        Constant.
2604  

2604  

2605  
        @par Exception Safety
2605  
        @par Exception Safety
2606  
        No-throw guarantee.
2606  
        No-throw guarantee.
2607  

2607  

2608  
        @{
2608  
        @{
2609  
    */
2609  
    */
2610  
    bool&
2610  
    bool&
2611  
    get_bool() noexcept
2611  
    get_bool() noexcept
2612  
    {
2612  
    {
2613  
        BOOST_ASSERT(is_bool());
2613  
        BOOST_ASSERT(is_bool());
2614  
        return sca_.b;
2614  
        return sca_.b;
2615  
    }
2615  
    }
2616  

2616  

2617  
    bool
2617  
    bool
2618  
    get_bool() const noexcept
2618  
    get_bool() const noexcept
2619  
    {
2619  
    {
2620  
        BOOST_ASSERT(is_bool());
2620  
        BOOST_ASSERT(is_bool());
2621  
        return sca_.b;
2621  
        return sca_.b;
2622  
    }
2622  
    }
2623  
    /// @}
2623  
    /// @}
2624  

2624  

2625  
    //------------------------------------------------------
2625  
    //------------------------------------------------------
2626  

2626  

2627  
    /** Access an element, with bounds checking.
2627  
    /** Access an element, with bounds checking.
2628  

2628  

2629  
        Returns `boost::system::result` containing a reference to the element
2629  
        Returns `boost::system::result` containing a reference to the element
2630  
        of the underlying ccontainer, if such element exists. If the underlying
2630  
        of the underlying ccontainer, if such element exists. If the underlying
2631  
        value is not a container of the suitable type or the container doesn't
2631  
        value is not a container of the suitable type or the container doesn't
2632  
        have a corresponding element the result contains an `error_code`.
2632  
        have a corresponding element the result contains an `error_code`.
2633  

2633  

2634  
        , if `pos` is within its range. If `pos` is
2634  
        , if `pos` is within its range. If `pos` is
2635  
        outside of that range, or the underlying value is not an object the
2635  
        outside of that range, or the underlying value is not an object the
2636  

2636  

2637  
        Returns @ref boost::system::result containing a reference to the
2637  
        Returns @ref boost::system::result containing a reference to the
2638  
        element of the underlying @ref array, if `pos` is within its range. If
2638  
        element of the underlying @ref array, if `pos` is within its range. If
2639  
        `pos` is outside of that range, or the underlying value is not an array
2639  
        `pos` is outside of that range, or the underlying value is not an array
2640  
        the result contains an `error_code`.
2640  
        the result contains an `error_code`.
2641  

2641  

2642  
        This function is used to access elements of
2642  
        This function is used to access elements of
2643  
        the underlying container, or throw an exception if that could not be
2643  
        the underlying container, or throw an exception if that could not be
2644  
        done.
2644  
        done.
2645  

2645  

2646  
        @li **(1)**, **(2)** require the underlying container to be an
2646  
        @li **(1)**, **(2)** require the underlying container to be an
2647  
            @ref object, and look for an element with the key `key`.
2647  
            @ref object, and look for an element with the key `key`.
2648  
        @li **(3)**, **(4)** require the underlying container to be an
2648  
        @li **(3)**, **(4)** require the underlying container to be an
2649  
            @ref array, and look  for an element at index `pos`.
2649  
            @ref array, and look  for an element at index `pos`.
2650  

2650  

2651  
        @par Exception Safety
2651  
        @par Exception Safety
2652  
        No-throw guarantee.
2652  
        No-throw guarantee.
2653  

2653  

2654  
        @param key The key of the element to find.
2654  
        @param key The key of the element to find.
2655  

2655  

2656  
        @par Complexity
2656  
        @par Complexity
2657  
        Constant.
2657  
        Constant.
2658  

2658  

2659  
        @par Exception Safety
2659  
        @par Exception Safety
2660  
        No-throw guarantee.
2660  
        No-throw guarantee.
2661  

2661  

2662  
        @{
2662  
        @{
2663  
    */
2663  
    */
2664  
    BOOST_JSON_DECL
2664  
    BOOST_JSON_DECL
2665  
    boost::system::result<value&>
2665  
    boost::system::result<value&>
2666  
    try_at(string_view key) noexcept;
2666  
    try_at(string_view key) noexcept;
2667  

2667  

2668  
    BOOST_JSON_DECL
2668  
    BOOST_JSON_DECL
2669  
    boost::system::result<value const&>
2669  
    boost::system::result<value const&>
2670  
    try_at(string_view key) const noexcept;
2670  
    try_at(string_view key) const noexcept;
2671  

2671  

2672  
    /** Overload
2672  
    /** Overload
2673  

2673  

2674  
        @param pos A zero-based array index.
2674  
        @param pos A zero-based array index.
2675  
    */
2675  
    */
2676  
    BOOST_JSON_DECL
2676  
    BOOST_JSON_DECL
2677  
    boost::system::result<value&>
2677  
    boost::system::result<value&>
2678  
    try_at(std::size_t pos) noexcept;
2678  
    try_at(std::size_t pos) noexcept;
2679  

2679  

2680  
    /// Overload
2680  
    /// Overload
2681  
    BOOST_JSON_DECL
2681  
    BOOST_JSON_DECL
2682  
    boost::system::result<value const&>
2682  
    boost::system::result<value const&>
2683  
    try_at(std::size_t pos) const noexcept;
2683  
    try_at(std::size_t pos) const noexcept;
2684  
    /// @}
2684  
    /// @}
2685  

2685  

2686  

2686  

2687  
    /** Access an element, with bounds checking.
2687  
    /** Access an element, with bounds checking.
2688  

2688  

2689  
        This function is used to access elements of
2689  
        This function is used to access elements of
2690  
        the underlying container, or throw an exception if that could not be
2690  
        the underlying container, or throw an exception if that could not be
2691  
        done.
2691  
        done.
2692  

2692  

2693  
        @li **(1)**--**(3)** is equivalent to
2693  
        @li **(1)**--**(3)** is equivalent to
2694  
            `this->as_object(loc).at(key, loc)`.
2694  
            `this->as_object(loc).at(key, loc)`.
2695  
        @li **(4)**--**(6)** is equivalent to
2695  
        @li **(4)**--**(6)** is equivalent to
2696  
            `this->as_array(loc).at(pos, loc)`.
2696  
            `this->as_array(loc).at(pos, loc)`.
2697  

2697  

2698  
        @par Complexity
2698  
        @par Complexity
2699  
        Constant.
2699  
        Constant.
2700  

2700  

2701  
        @par Exception Safety
2701  
        @par Exception Safety
2702  
        Strong guarantee.
2702  
        Strong guarantee.
2703  

2703  

2704  
        @param key The key of the element to find.
2704  
        @param key The key of the element to find.
2705  
        @param loc @ref boost::source_location to use in thrown exception; the
2705  
        @param loc @ref boost::source_location to use in thrown exception; the
2706  
               source location of the call site by default.
2706  
               source location of the call site by default.
2707  

2707  

2708  
        @throw boost::system::system_error The underlying type of value is not
2708  
        @throw boost::system::system_error The underlying type of value is not
2709  
               the container type corresponding to the first argument (i.e.
2709  
               the container type corresponding to the first argument (i.e.
2710  
               using an index with an @ref object).
2710  
               using an index with an @ref object).
2711  
        @throw boost::system::system_error An element corresponding to the
2711  
        @throw boost::system::system_error An element corresponding to the
2712  
               first argument was not found.
2712  
               first argument was not found.
2713  

2713  

2714  
        @see @ref as_array, @ref as_object.
2714  
        @see @ref as_array, @ref as_object.
2715  

2715  

2716  
        @{
2716  
        @{
2717  
    */
2717  
    */
2718  
    value&
2718  
    value&
2719  
    at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
2719  
    at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
2720  
    {
2720  
    {
2721  
        return as_object(loc).at(key, loc);
2721  
        return as_object(loc).at(key, loc);
2722  
    }
2722  
    }
2723  

2723  

2724  
    /// Overload
2724  
    /// Overload
2725  
    value&&
2725  
    value&&
2726  
    at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2726  
    at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2727  
    {
2727  
    {
2728  
        return std::move( as_object(loc) ).at(key, loc);
2728  
        return std::move( as_object(loc) ).at(key, loc);
2729  
    }
2729  
    }
2730  

2730  

2731  
    /// Overload
2731  
    /// Overload
2732  
    value const&
2732  
    value const&
2733  
    at(
2733  
    at(
2734  
        string_view key,
2734  
        string_view key,
2735  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&
2735  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&
2736  
    {
2736  
    {
2737  
        return as_object(loc).at(key, loc);
2737  
        return as_object(loc).at(key, loc);
2738  
    }
2738  
    }
2739  

2739  

2740  
    /** Overload
2740  
    /** Overload
2741  

2741  

2742  
        @param pos A zero-based array index.
2742  
        @param pos A zero-based array index.
2743  
        @param loc
2743  
        @param loc
2744  
    */
2744  
    */
2745  
    value &
2745  
    value &
2746  
    at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
2746  
    at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
2747  
    {
2747  
    {
2748  
        return as_array(loc).at(pos, loc);
2748  
        return as_array(loc).at(pos, loc);
2749  
    }
2749  
    }
2750  

2750  

2751  
    /// Overload
2751  
    /// Overload
2752  
    value&&
2752  
    value&&
2753  
    at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2753  
    at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2754  
    {
2754  
    {
2755  
        return std::move( as_array(loc) ).at(pos, loc);
2755  
        return std::move( as_array(loc) ).at(pos, loc);
2756  
    }
2756  
    }
2757  

2757  

2758  
    /// Overload
2758  
    /// Overload
2759  
    value const&
2759  
    value const&
2760  
    at(std::size_t pos,
2760  
    at(std::size_t pos,
2761  
       source_location const& loc = BOOST_CURRENT_LOCATION) const&
2761  
       source_location const& loc = BOOST_CURRENT_LOCATION) const&
2762  
    {
2762  
    {
2763  
        return as_array(loc).at(pos, loc);
2763  
        return as_array(loc).at(pos, loc);
2764  
    }
2764  
    }
2765  
    /// @}
2765  
    /// @}
2766  

2766  

2767  
    /** Access an element via JSON Pointer.
2767  
    /** Access an element via JSON Pointer.
2768  

2768  

2769  
        This function is used to access a (potentially nested) element of the
2769  
        This function is used to access a (potentially nested) element of the
2770  
        value using a JSON Pointer string.
2770  
        value using a JSON Pointer string.
2771  

2771  

2772  
        @par Complexity
2772  
        @par Complexity
2773  
        Linear in the sizes of `ptr` and underlying array, object, or string.
2773  
        Linear in the sizes of `ptr` and underlying array, object, or string.
2774  

2774  

2775  
        @par Exception Safety
2775  
        @par Exception Safety
2776  
        No-throw guarantee.
2776  
        No-throw guarantee.
2777  

2777  

2778  
        @param ptr JSON Pointer string.
2778  
        @param ptr JSON Pointer string.
2779  

2779  

2780  
        @return @ref boost::system::result containing either a reference to the
2780  
        @return @ref boost::system::result containing either a reference to the
2781  
                element identified by `ptr` or a corresponding `error_code`.
2781  
                element identified by `ptr` or a corresponding `error_code`.
2782  

2782  

2783  
        @see
2783  
        @see
2784  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2784  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2785  

2785  

2786  
        @{
2786  
        @{
2787  
    */
2787  
    */
2788  
    BOOST_JSON_DECL
2788  
    BOOST_JSON_DECL
2789  
    system::result<value const&>
2789  
    system::result<value const&>
2790  
    try_at_pointer(string_view ptr) const noexcept;
2790  
    try_at_pointer(string_view ptr) const noexcept;
2791  

2791  

2792  
    BOOST_JSON_DECL
2792  
    BOOST_JSON_DECL
2793  
    system::result<value&>
2793  
    system::result<value&>
2794  
    try_at_pointer(string_view ptr) noexcept;
2794  
    try_at_pointer(string_view ptr) noexcept;
2795  
    /// @}
2795  
    /// @}
2796  

2796  

2797  
    /** Access an element via JSON Pointer.
2797  
    /** Access an element via JSON Pointer.
2798  

2798  

2799  
        This function is used to access a (potentially nested) element of the
2799  
        This function is used to access a (potentially nested) element of the
2800  
        value using a JSON Pointer string.
2800  
        value using a JSON Pointer string.
2801  

2801  

2802  
        @par Complexity
2802  
        @par Complexity
2803  
        Linear in the sizes of `ptr` and the underlying container.
2803  
        Linear in the sizes of `ptr` and the underlying container.
2804  

2804  

2805  
        @par Exception Safety
2805  
        @par Exception Safety
2806  
        Strong guarantee.
2806  
        Strong guarantee.
2807  

2807  

2808  
        @param ptr JSON Pointer string.
2808  
        @param ptr JSON Pointer string.
2809  
        @param loc @ref boost::source_location to use in thrown exception; the
2809  
        @param loc @ref boost::source_location to use in thrown exception; the
2810  
               source location of the call site by default.
2810  
               source location of the call site by default.
2811  

2811  

2812  
        @return reference to the element identified by `ptr`.
2812  
        @return reference to the element identified by `ptr`.
2813  

2813  

2814  
        @throw boost::system::system_error if an error occurs.
2814  
        @throw boost::system::system_error if an error occurs.
2815  

2815  

2816  
        @see
2816  
        @see
2817  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2817  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2818  

2818  

2819  
        @{
2819  
        @{
2820  
    */
2820  
    */
2821  
    BOOST_JSON_DECL
2821  
    BOOST_JSON_DECL
2822  
    value const&
2822  
    value const&
2823  
    at_pointer(
2823  
    at_pointer(
2824  
        string_view ptr,
2824  
        string_view ptr,
2825  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2825  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2826  

2826  

2827  
    /// Overload
2827  
    /// Overload
2828  
    inline
2828  
    inline
2829  
    value&&
2829  
    value&&
2830  
    at_pointer(
2830  
    at_pointer(
2831  
        string_view ptr,
2831  
        string_view ptr,
2832  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
2832  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
2833  

2833  

2834  
    /// Overload
2834  
    /// Overload
2835  
    inline
2835  
    inline
2836  
    value&
2836  
    value&
2837  
    at_pointer(
2837  
    at_pointer(
2838  
        string_view ptr,
2838  
        string_view ptr,
2839  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
2839  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
2840  
    /// @}
2840  
    /// @}
2841  

2841  

2842  
    /** Access an element via JSON Pointer.
2842  
    /** Access an element via JSON Pointer.
2843  

2843  

2844  
        This function is used to access a (potentially nested) element of the
2844  
        This function is used to access a (potentially nested) element of the
2845  
        value using a JSON Pointer string.
2845  
        value using a JSON Pointer string.
2846  

2846  

2847  
        @par Complexity
2847  
        @par Complexity
2848  
        Linear in the sizes of `ptr` and underlying container.
2848  
        Linear in the sizes of `ptr` and underlying container.
2849  

2849  

2850  
        @par Exception Safety
2850  
        @par Exception Safety
2851  
        No-throw guarantee.
2851  
        No-throw guarantee.
2852  

2852  

2853  
        @param ptr JSON Pointer string.
2853  
        @param ptr JSON Pointer string.
2854  
        @param ec Set to the error, if any occurred.
2854  
        @param ec Set to the error, if any occurred.
2855  

2855  

2856  
        @return pointer to the element identified by `ptr`.
2856  
        @return pointer to the element identified by `ptr`.
2857  

2857  

2858  
        @see
2858  
        @see
2859  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
2859  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
2860  

2860  

2861  
        @{
2861  
        @{
2862  
    */
2862  
    */
2863  
    BOOST_JSON_DECL
2863  
    BOOST_JSON_DECL
2864  
    value const*
2864  
    value const*
2865  
    find_pointer(string_view ptr, system::error_code& ec) const noexcept;
2865  
    find_pointer(string_view ptr, system::error_code& ec) const noexcept;
2866  

2866  

2867  
    BOOST_JSON_DECL
2867  
    BOOST_JSON_DECL
2868  
    value*
2868  
    value*
2869  
    find_pointer(string_view ptr, system::error_code& ec) noexcept;
2869  
    find_pointer(string_view ptr, system::error_code& ec) noexcept;
2870  

2870  

2871  
    BOOST_JSON_DECL
2871  
    BOOST_JSON_DECL
2872  
    value const*
2872  
    value const*
2873  
    find_pointer(string_view ptr, std::error_code& ec) const noexcept;
2873  
    find_pointer(string_view ptr, std::error_code& ec) const noexcept;
2874  

2874  

2875  
    BOOST_JSON_DECL
2875  
    BOOST_JSON_DECL
2876  
    value*
2876  
    value*
2877  
    find_pointer(string_view ptr, std::error_code& ec) noexcept;
2877  
    find_pointer(string_view ptr, std::error_code& ec) noexcept;
2878  
    /// @}
2878  
    /// @}
2879  

2879  

2880  
    //------------------------------------------------------
2880  
    //------------------------------------------------------
2881  

2881  

2882  
    /** Set an element via JSON Pointer.
2882  
    /** Set an element via JSON Pointer.
2883  

2883  

2884  
        This function is used to insert or assign to a potentially nested
2884  
        This function is used to insert or assign to a potentially nested
2885  
        element of the value using a JSON Pointer string. The function may
2885  
        element of the value using a JSON Pointer string. The function may
2886  
        create intermediate elements corresponding to pointer segments.
2886  
        create intermediate elements corresponding to pointer segments.
2887  

2887  

2888  
        The particular conditions when and what kind of intermediate element
2888  
        The particular conditions when and what kind of intermediate element
2889  
        is created is governed by the `ptr` parameter.
2889  
        is created is governed by the `ptr` parameter.
2890  

2890  

2891  
        Each pointer token is considered in sequence. For each token
2891  
        Each pointer token is considered in sequence. For each token
2892  

2892  

2893  
        - if the containing value is an @ref object, then a new `null`
2893  
        - if the containing value is an @ref object, then a new `null`
2894  
          element is created with key equal to unescaped token string;
2894  
          element is created with key equal to unescaped token string;
2895  
          otherwise
2895  
          otherwise
2896  

2896  

2897  
        - if the containing value is an @ref array, and the token represents a
2897  
        - if the containing value is an @ref array, and the token represents a
2898  
          past-the-end marker, then a `null` element is appended to the array;
2898  
          past-the-end marker, then a `null` element is appended to the array;
2899  
          otherwise
2899  
          otherwise
2900  

2900  

2901  
        - if the containing value is an @ref array, and the token represents a
2901  
        - if the containing value is an @ref array, and the token represents a
2902  
          number, then if the difference between the number and array's size
2902  
          number, then if the difference between the number and array's size
2903  
          is smaller than `opts.max_created_elements`, then the size of the
2903  
          is smaller than `opts.max_created_elements`, then the size of the
2904  
          array is increased, so that the number can reference an element in the
2904  
          array is increased, so that the number can reference an element in the
2905  
          array; otherwise
2905  
          array; otherwise
2906  

2906  

2907  
        - if the containing value is of different @ref kind and
2907  
        - if the containing value is of different @ref kind and
2908  
          `opts.replace_any_scalar` is `true`, or the value is `null`, then
2908  
          `opts.replace_any_scalar` is `true`, or the value is `null`, then
2909  

2909  

2910  
           - if `opts.create_arrays` is `true` and the token either represents
2910  
           - if `opts.create_arrays` is `true` and the token either represents
2911  
             past-the-end marker or a number, then the value is replaced with
2911  
             past-the-end marker or a number, then the value is replaced with
2912  
             an empty array and the token is considered again; otherwise
2912  
             an empty array and the token is considered again; otherwise
2913  

2913  

2914  
           - if `opts.create_objects` is `true`, then the value is replaced
2914  
           - if `opts.create_objects` is `true`, then the value is replaced
2915  
             with an empty object and the token is considered again; otherwise
2915  
             with an empty object and the token is considered again; otherwise
2916  

2916  

2917  
        - an error is produced.
2917  
        - an error is produced.
2918  

2918  

2919  
        @par Complexity
2919  
        @par Complexity
2920  
        Linear in the sum of size of `ptr`, size of underlying array, object,
2920  
        Linear in the sum of size of `ptr`, size of underlying array, object,
2921  
        or string and `opts.max_created_elements`.
2921  
        or string and `opts.max_created_elements`.
2922  

2922  

2923  
        @par Exception Safety
2923  
        @par Exception Safety
2924  
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
2924  
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
2925  

2925  

2926  
        @param sv JSON Pointer string.
2926  
        @param sv JSON Pointer string.
2927  
        @param ref The value to assign to pointed element.
2927  
        @param ref The value to assign to pointed element.
2928  
        @param opts The options for the algorithm.
2928  
        @param opts The options for the algorithm.
2929  

2929  

2930  
        @return @ref boost::system::result containing either a reference to the
2930  
        @return @ref boost::system::result containing either a reference to the
2931  
                element identified by `ptr` or a corresponding `error_code`.
2931  
                element identified by `ptr` or a corresponding `error_code`.
2932  

2932  

2933  
        @see
2933  
        @see
2934  
            @ref set_pointer_options,
2934  
            @ref set_pointer_options,
2935  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2935  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2936  
    */
2936  
    */
2937  
    BOOST_JSON_DECL
2937  
    BOOST_JSON_DECL
2938  
    system::result<value&>
2938  
    system::result<value&>
2939  
    try_set_at_pointer(
2939  
    try_set_at_pointer(
2940  
        string_view sv,
2940  
        string_view sv,
2941  
        value_ref ref,
2941  
        value_ref ref,
2942  
        set_pointer_options const& opts = {} );
2942  
        set_pointer_options const& opts = {} );
2943  

2943  

2944  
    /** Set an element via JSON Pointer.
2944  
    /** Set an element via JSON Pointer.
2945  

2945  

2946  
        This function is used to insert or assign to a potentially nested
2946  
        This function is used to insert or assign to a potentially nested
2947  
        element of the value using a JSON Pointer string. The function may
2947  
        element of the value using a JSON Pointer string. The function may
2948  
        create intermediate elements corresponding to pointer segments.
2948  
        create intermediate elements corresponding to pointer segments.
2949  

2949  

2950  
        The particular conditions when and what kind of intermediate element
2950  
        The particular conditions when and what kind of intermediate element
2951  
        is created is governed by the `ptr` parameter.
2951  
        is created is governed by the `ptr` parameter.
2952  

2952  

2953  
        Each pointer token is considered in sequence. For each token
2953  
        Each pointer token is considered in sequence. For each token
2954  

2954  

2955  
        - if the containing value is an @ref object, then a new `null`
2955  
        - if the containing value is an @ref object, then a new `null`
2956  
        element is created with key equal to unescaped token string; otherwise
2956  
        element is created with key equal to unescaped token string; otherwise
2957  

2957  

2958  
        - if the containing value is an @ref array, and the token represents a
2958  
        - if the containing value is an @ref array, and the token represents a
2959  
        past-the-end marker, then a `null` element is appended to the array;
2959  
        past-the-end marker, then a `null` element is appended to the array;
2960  
        otherwise
2960  
        otherwise
2961  

2961  

2962  
        - if the containing value is an @ref array, and the token represents a
2962  
        - if the containing value is an @ref array, and the token represents a
2963  
        number, then if the difference between the number and array's size
2963  
        number, then if the difference between the number and array's size
2964  
        is smaller than `opts.max_created_elements`, then the size of the
2964  
        is smaller than `opts.max_created_elements`, then the size of the
2965  
        array is increased, so that the number can reference an element in the
2965  
        array is increased, so that the number can reference an element in the
2966  
        array; otherwise
2966  
        array; otherwise
2967  

2967  

2968  
        - if the containing value is of different @ref kind and
2968  
        - if the containing value is of different @ref kind and
2969  
          `opts.replace_any_scalar` is `true`, or the value is `null`, then
2969  
          `opts.replace_any_scalar` is `true`, or the value is `null`, then
2970  

2970  

2971  
           - if `opts.create_arrays` is `true` and the token either represents
2971  
           - if `opts.create_arrays` is `true` and the token either represents
2972  
             past-the-end marker or a number, then the value is replaced with
2972  
             past-the-end marker or a number, then the value is replaced with
2973  
             an empty array and the token is considered again; otherwise
2973  
             an empty array and the token is considered again; otherwise
2974  

2974  

2975  
           - if `opts.create_objects` is `true`, then the value is replaced
2975  
           - if `opts.create_objects` is `true`, then the value is replaced
2976  
             with an empty object and the token is considered again; otherwise
2976  
             with an empty object and the token is considered again; otherwise
2977  

2977  

2978  
        - an error is produced.
2978  
        - an error is produced.
2979  

2979  

2980  
        @par Complexity
2980  
        @par Complexity
2981  
        Linear in the sum of size of `ptr`, size of underlying array, object,
2981  
        Linear in the sum of size of `ptr`, size of underlying array, object,
2982  
        or string and `opts.max_created_elements`.
2982  
        or string and `opts.max_created_elements`.
2983  

2983  

2984  
        @par Exception Safety
2984  
        @par Exception Safety
2985  
        Basic guarantee.
2985  
        Basic guarantee.
2986  
        Calls to `memory_resource::allocate` may throw.
2986  
        Calls to `memory_resource::allocate` may throw.
2987  

2987  

2988  
        @param sv JSON Pointer string.
2988  
        @param sv JSON Pointer string.
2989  

2989  

2990  
        @param ref The value to assign to pointed element.
2990  
        @param ref The value to assign to pointed element.
2991  

2991  

2992  
        @param opts The options for the algorithm.
2992  
        @param opts The options for the algorithm.
2993  

2993  

2994  
        @return Reference to the element identified by `ptr`.
2994  
        @return Reference to the element identified by `ptr`.
2995  

2995  

2996  
        @throws boost::system::system_error Overload **(1)** reports errors by
2996  
        @throws boost::system::system_error Overload **(1)** reports errors by
2997  
                throwing exceptions.
2997  
                throwing exceptions.
2998  

2998  

2999  
        @see @ref set_pointer_options,
2999  
        @see @ref set_pointer_options,
3000  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
3000  
            [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
3001  

3001  

3002  
        @{
3002  
        @{
3003  
    */
3003  
    */
3004  
    BOOST_JSON_DECL
3004  
    BOOST_JSON_DECL
3005  
    value&
3005  
    value&
3006  
    set_at_pointer(
3006  
    set_at_pointer(
3007  
        string_view sv,
3007  
        string_view sv,
3008  
        value_ref ref,
3008  
        value_ref ref,
3009  
        set_pointer_options const& opts = {} );
3009  
        set_pointer_options const& opts = {} );
3010  

3010  

3011  
    /** Overload
3011  
    /** Overload
3012  

3012  

3013  
        @param ec Set to the error, if any occurred.
3013  
        @param ec Set to the error, if any occurred.
3014  
        @param sv
3014  
        @param sv
3015  
        @param ref
3015  
        @param ref
3016  
        @param opts
3016  
        @param opts
3017  
    */
3017  
    */
3018  
    BOOST_JSON_DECL
3018  
    BOOST_JSON_DECL
3019  
    value*
3019  
    value*
3020  
    set_at_pointer(
3020  
    set_at_pointer(
3021  
        string_view sv,
3021  
        string_view sv,
3022  
        value_ref ref,
3022  
        value_ref ref,
3023  
        system::error_code& ec,
3023  
        system::error_code& ec,
3024  
        set_pointer_options const& opts = {} );
3024  
        set_pointer_options const& opts = {} );
3025  

3025  

3026  
    /// Overload
3026  
    /// Overload
3027  
    BOOST_JSON_DECL
3027  
    BOOST_JSON_DECL
3028  
    value*
3028  
    value*
3029  
    set_at_pointer(
3029  
    set_at_pointer(
3030  
        string_view sv,
3030  
        string_view sv,
3031  
        value_ref ref,
3031  
        value_ref ref,
3032  
        std::error_code& ec,
3032  
        std::error_code& ec,
3033  
        set_pointer_options const& opts = {} );
3033  
        set_pointer_options const& opts = {} );
3034  
    /// @}
3034  
    /// @}
3035  

3035  

3036  
    //------------------------------------------------------
3036  
    //------------------------------------------------------
3037  

3037  

 
3038 +
    /** Remove an element via JSON Pointer.
 
3039 +

 
3040 +
        @{
 
3041 +
    */
 
3042 +
    BOOST_JSON_DECL
 
3043 +
    bool
 
3044 +
    erase_at_pointer(
 
3045 +
        string_view         sv,
 
3046 +
        system::error_code& ec);
 
3047 +

 
3048 +
    /// @}
 
3049 +
    //------------------------------------------------------
 
3050 +

3038  
    /** Check if two values are equal.
3051  
    /** Check if two values are equal.
3039  

3052  

3040  
        Two values are equal when they are the same kind and their referenced
3053  
        Two values are equal when they are the same kind and their referenced
3041  
        values are equal, or when they are both integral types and their
3054  
        values are equal, or when they are both integral types and their
3042  
        integral representations are equal.
3055  
        integral representations are equal.
3043  

3056  

3044  
        @par Complexity
3057  
        @par Complexity
3045  
        Constant or linear in the size of the underlying @ref array, @ref object,
3058  
        Constant or linear in the size of the underlying @ref array, @ref object,
3046  
        or @ref string.
3059  
        or @ref string.
3047  

3060  

3048  
        @par Exception Safety
3061  
        @par Exception Safety
3049  
        No-throw guarantee.
3062  
        No-throw guarantee.
3050  
    */
3063  
    */
3051  
    // inline friend speeds up overload resolution
3064  
    // inline friend speeds up overload resolution
3052  
    friend
3065  
    friend
3053  
    bool
3066  
    bool
3054  
    operator==(
3067  
    operator==(
3055  
        value const& lhs,
3068  
        value const& lhs,
3056  
        value const& rhs) noexcept
3069  
        value const& rhs) noexcept
3057  
    {
3070  
    {
3058  
        return lhs.equal(rhs);
3071  
        return lhs.equal(rhs);
3059  
    }
3072  
    }
3060  

3073  

3061  
    /** Check if two values are not equal.
3074  
    /** Check if two values are not equal.
3062  

3075  

3063  
        Two values are equal when they are the same kind and their referenced
3076  
        Two values are equal when they are the same kind and their referenced
3064  
        values are equal, or when they are both integral types and their
3077  
        values are equal, or when they are both integral types and their
3065  
        integral representations are equal.
3078  
        integral representations are equal.
3066  

3079  

3067  
        @par Complexity
3080  
        @par Complexity
3068  
        Constant or linear in the size of the underlying @ref array,
3081  
        Constant or linear in the size of the underlying @ref array,
3069  
        @ref object, or @ref string.
3082  
        @ref object, or @ref string.
3070  

3083  

3071  
        @par Exception Safety
3084  
        @par Exception Safety
3072  
        No-throw guarantee.
3085  
        No-throw guarantee.
3073  
    */
3086  
    */
3074  
    friend
3087  
    friend
3075  
    bool
3088  
    bool
3076  
    operator!=(
3089  
    operator!=(
3077  
        value const& lhs,
3090  
        value const& lhs,
3078  
        value const& rhs) noexcept
3091  
        value const& rhs) noexcept
3079  
    {
3092  
    {
3080  
        return ! (lhs == rhs);
3093  
        return ! (lhs == rhs);
3081  
    }
3094  
    }
3082  

3095  

3083  
    /** Serialize @ref value to an output stream.
3096  
    /** Serialize @ref value to an output stream.
3084  

3097  

3085  
        This function serializes a `value` as JSON text into the output stream.
3098  
        This function serializes a `value` as JSON text into the output stream.
3086  

3099  

3087  
        @return Reference to `os`.
3100  
        @return Reference to `os`.
3088  

3101  

3089  
        @par Complexity
3102  
        @par Complexity
3090  
        Constant or linear in the size of `jv`.
3103  
        Constant or linear in the size of `jv`.
3091  

3104  

3092  
        @par Exception Safety
3105  
        @par Exception Safety
3093  
        Strong guarantee.
3106  
        Strong guarantee.
3094  
        Calls to `memory_resource::allocate` may throw.
3107  
        Calls to `memory_resource::allocate` may throw.
3095  

3108  

3096  
        @param os The output stream to serialize to.
3109  
        @param os The output stream to serialize to.
3097  

3110  

3098  
        @param jv The value to serialize.
3111  
        @param jv The value to serialize.
3099  
    */
3112  
    */
3100  
    BOOST_JSON_DECL
3113  
    BOOST_JSON_DECL
3101  
    friend
3114  
    friend
3102  
    std::ostream&
3115  
    std::ostream&
3103  
    operator<<(
3116  
    operator<<(
3104  
        std::ostream& os,
3117  
        std::ostream& os,
3105  
        value const& jv);
3118  
        value const& jv);
3106  

3119  

3107  
    /** Parse @ref value from an input stream.
3120  
    /** Parse @ref value from an input stream.
3108  

3121  

3109  
        This function parses JSON from an input stream into a `value`. If
3122  
        This function parses JSON from an input stream into a `value`. If
3110  
        parsing fails, @ref std::ios_base::failbit will be set for `is` and
3123  
        parsing fails, @ref std::ios_base::failbit will be set for `is` and
3111  
        `jv` will be left unchanged. Regardless of whether @ref
3124  
        `jv` will be left unchanged. Regardless of whether @ref
3112  
        std::ios_base::skipws flag is set on `is`, consumes whitespace before
3125  
        std::ios_base::skipws flag is set on `is`, consumes whitespace before
3113  
        and after JSON, because whitespace is considered a part of JSON.
3126  
        and after JSON, because whitespace is considered a part of JSON.
3114  
        Behaves as
3127  
        Behaves as
3115  
        [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
3128  
        [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
3116  

3129  

3117  
        @note This operator cannot assume that the stream only contains a
3130  
        @note This operator cannot assume that the stream only contains a
3118  
        single JSON document, which may result in **very underwhelming
3131  
        single JSON document, which may result in **very underwhelming
3119  
        performance**, if the stream isn't cooperative. If you know that your
3132  
        performance**, if the stream isn't cooperative. If you know that your
3120  
        input consists of a single JSON document, consider using @ref parse
3133  
        input consists of a single JSON document, consider using @ref parse
3121  
        function instead.
3134  
        function instead.
3122  

3135  

3123  
        @return Reference to `is`.
3136  
        @return Reference to `is`.
3124  

3137  

3125  
        @par Complexity
3138  
        @par Complexity
3126  
        Linear in the size of JSON data.
3139  
        Linear in the size of JSON data.
3127  

3140  

3128  
        @par Exception Safety
3141  
        @par Exception Safety
3129  
        Basic guarantee.
3142  
        Basic guarantee.
3130  
        Calls to `memory_resource::allocate` may throw.
3143  
        Calls to `memory_resource::allocate` may throw.
3131  
        The stream may throw as configured by @ref std::ios::exceptions.
3144  
        The stream may throw as configured by @ref std::ios::exceptions.
3132  

3145  

3133  
        @param is The input stream to parse from.
3146  
        @param is The input stream to parse from.
3134  

3147  

3135  
        @param jv The value to parse into.
3148  
        @param jv The value to parse into.
3136  

3149  

3137  
        @see @ref parse.
3150  
        @see @ref parse.
3138  
    */
3151  
    */
3139  
    BOOST_JSON_DECL
3152  
    BOOST_JSON_DECL
3140  
    friend
3153  
    friend
3141  
    std::istream&
3154  
    std::istream&
3142  
    operator>>(
3155  
    operator>>(
3143  
        std::istream& is,
3156  
        std::istream& is,
3144  
        value& jv);
3157  
        value& jv);
3145  

3158  

3146  
    /** Helper for @ref boost::hash support.
3159  
    /** Helper for @ref boost::hash support.
3147  

3160  

3148  
        Computes a hash value for `jv`. This function is used by
3161  
        Computes a hash value for `jv`. This function is used by
3149  
        `boost::hash<value>`. Similar overloads for @ref array, @ref object,
3162  
        `boost::hash<value>`. Similar overloads for @ref array, @ref object,
3150  
        and @ref string do not exist, because those types are supported by
3163  
        and @ref string do not exist, because those types are supported by
3151  
        `boost::hash` out of the box.
3164  
        `boost::hash` out of the box.
3152  

3165  

3153  
        @return hash value for `jv`.
3166  
        @return hash value for `jv`.
3154  

3167  

3155  
        @param jv `value` for which a hash is to be computed.
3168  
        @param jv `value` for which a hash is to be computed.
3156  

3169  

3157  
        @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
3170  
        @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
3158  
     */
3171  
     */
3159  
#ifndef BOOST_JSON_DOCS
3172  
#ifndef BOOST_JSON_DOCS
3160  
    template<
3173  
    template<
3161  
        class T,
3174  
        class T,
3162  
        typename std::enable_if<
3175  
        typename std::enable_if<
3163  
            std::is_same< detail::remove_cvref<T>, value >::value >::type*
3176  
            std::is_same< detail::remove_cvref<T>, value >::value >::type*
3164  
                = nullptr>
3177  
                = nullptr>
3165  
    friend
3178  
    friend
3166  
    std::size_t
3179  
    std::size_t
3167  
    hash_value( T const& jv ) noexcept
3180  
    hash_value( T const& jv ) noexcept
3168  
#else
3181  
#else
3169  
    friend
3182  
    friend
3170  
    inline
3183  
    inline
3171  
    std::size_t
3184  
    std::size_t
3172  
    hash_value( value const& jv ) noexcept
3185  
    hash_value( value const& jv ) noexcept
3173  
#endif
3186  
#endif
3174  
    {
3187  
    {
3175  
        return detail::hash_value_impl(jv);
3188  
        return detail::hash_value_impl(jv);
3176  
    }
3189  
    }
3177  

3190  

3178  
private:
3191  
private:
3179  
    static
3192  
    static
3180  
    void
3193  
    void
3181  
    relocate(
3194  
    relocate(
3182  
        value* dest,
3195  
        value* dest,
3183  
        value const& src) noexcept
3196  
        value const& src) noexcept
3184  
    {
3197  
    {
3185  
        std::memcpy(
3198  
        std::memcpy(
3186  
            static_cast<void*>(dest),
3199  
            static_cast<void*>(dest),
3187  
            &src,
3200  
            &src,
3188  
            sizeof(src));
3201  
            sizeof(src));
3189  
    }
3202  
    }
3190  

3203  

3191  
    BOOST_JSON_DECL
3204  
    BOOST_JSON_DECL
3192  
    storage_ptr
3205  
    storage_ptr
3193  
    destroy() noexcept;
3206  
    destroy() noexcept;
3194  

3207  

3195  
    BOOST_JSON_DECL
3208  
    BOOST_JSON_DECL
3196  
    bool
3209  
    bool
3197  
    equal(value const& other) const noexcept;
3210  
    equal(value const& other) const noexcept;
3198  

3211  

3199  
    template<class T>
3212  
    template<class T>
3200  
    auto
3213  
    auto
3201  
    to_number(error& e) const noexcept ->
3214  
    to_number(error& e) const noexcept ->
3202  
        typename std::enable_if<
3215  
        typename std::enable_if<
3203  
            std::is_signed<T>::value &&
3216  
            std::is_signed<T>::value &&
3204  
            ! std::is_floating_point<T>::value,
3217  
            ! std::is_floating_point<T>::value,
3205  
                T>::type
3218  
                T>::type
3206  
    {
3219  
    {
3207  
        if(sca_.k == json::kind::int64)
3220  
        if(sca_.k == json::kind::int64)
3208  
        {
3221  
        {
3209  
            auto const i = sca_.i;
3222  
            auto const i = sca_.i;
3210  
            if( i >= (std::numeric_limits<T>::min)() &&
3223  
            if( i >= (std::numeric_limits<T>::min)() &&
3211  
                i <= (std::numeric_limits<T>::max)())
3224  
                i <= (std::numeric_limits<T>::max)())
3212  
            {
3225  
            {
3213  
                e = {};
3226  
                e = {};
3214  
                return static_cast<T>(i);
3227  
                return static_cast<T>(i);
3215  
            }
3228  
            }
3216  
            e = error::not_exact;
3229  
            e = error::not_exact;
3217  
        }
3230  
        }
3218  
        else if(sca_.k == json::kind::uint64)
3231  
        else if(sca_.k == json::kind::uint64)
3219  
        {
3232  
        {
3220  
            auto const u = sca_.u;
3233  
            auto const u = sca_.u;
3221  
            if(u <= static_cast<std::uint64_t>((
3234  
            if(u <= static_cast<std::uint64_t>((
3222  
                std::numeric_limits<T>::max)()))
3235  
                std::numeric_limits<T>::max)()))
3223  
            {
3236  
            {
3224  
                e = {};
3237  
                e = {};
3225  
                return static_cast<T>(u);
3238  
                return static_cast<T>(u);
3226  
            }
3239  
            }
3227  
            e = error::not_exact;
3240  
            e = error::not_exact;
3228  
        }
3241  
        }
3229  
        else if(sca_.k == json::kind::double_)
3242  
        else if(sca_.k == json::kind::double_)
3230  
        {
3243  
        {
3231  
            auto const d = sca_.d;
3244  
            auto const d = sca_.d;
3232  
            if( d >= static_cast<double>(
3245  
            if( d >= static_cast<double>(
3233  
                    (detail::to_number_limit<T>::min)()) &&
3246  
                    (detail::to_number_limit<T>::min)()) &&
3234  
                d <= static_cast<double>(
3247  
                d <= static_cast<double>(
3235  
                    (detail::to_number_limit<T>::max)()) &&
3248  
                    (detail::to_number_limit<T>::max)()) &&
3236  
                static_cast<T>(d) == d)
3249  
                static_cast<T>(d) == d)
3237  
            {
3250  
            {
3238  
                e = {};
3251  
                e = {};
3239  
                return static_cast<T>(d);
3252  
                return static_cast<T>(d);
3240  
            }
3253  
            }
3241  
            e = error::not_exact;
3254  
            e = error::not_exact;
3242  
        }
3255  
        }
3243  
        else
3256  
        else
3244  
        {
3257  
        {
3245  
            e = error::not_number;
3258  
            e = error::not_number;
3246  
        }
3259  
        }
3247  
        return T{};
3260  
        return T{};
3248  
    }
3261  
    }
3249  

3262  

3250  
    template<class T>
3263  
    template<class T>
3251  
    auto
3264  
    auto
3252  
    to_number(error& e) const noexcept ->
3265  
    to_number(error& e) const noexcept ->
3253  
        typename std::enable_if<
3266  
        typename std::enable_if<
3254  
            std::is_unsigned<T>::value &&
3267  
            std::is_unsigned<T>::value &&
3255  
            ! std::is_same<T, bool>::value,
3268  
            ! std::is_same<T, bool>::value,
3256  
                T>::type
3269  
                T>::type
3257  
    {
3270  
    {
3258  
        if(sca_.k == json::kind::int64)
3271  
        if(sca_.k == json::kind::int64)
3259  
        {
3272  
        {
3260  
            auto const i = sca_.i;
3273  
            auto const i = sca_.i;
3261  
            if( i >= 0 && static_cast<std::uint64_t>(i) <=
3274  
            if( i >= 0 && static_cast<std::uint64_t>(i) <=
3262  
                (std::numeric_limits<T>::max)())
3275  
                (std::numeric_limits<T>::max)())
3263  
            {
3276  
            {
3264  
                e = {};
3277  
                e = {};
3265  
                return static_cast<T>(i);
3278  
                return static_cast<T>(i);
3266  
            }
3279  
            }
3267  
            e = error::not_exact;
3280  
            e = error::not_exact;
3268  
        }
3281  
        }
3269  
        else if(sca_.k == json::kind::uint64)
3282  
        else if(sca_.k == json::kind::uint64)
3270  
        {
3283  
        {
3271  
            auto const u = sca_.u;
3284  
            auto const u = sca_.u;
3272  
            if(u <= (std::numeric_limits<T>::max)())
3285  
            if(u <= (std::numeric_limits<T>::max)())
3273  
            {
3286  
            {
3274  
                e = {};
3287  
                e = {};
3275  
                return static_cast<T>(u);
3288  
                return static_cast<T>(u);
3276  
            }
3289  
            }
3277  
            e = error::not_exact;
3290  
            e = error::not_exact;
3278  
        }
3291  
        }
3279  
        else if(sca_.k == json::kind::double_)
3292  
        else if(sca_.k == json::kind::double_)
3280  
        {
3293  
        {
3281  
            auto const d = sca_.d;
3294  
            auto const d = sca_.d;
3282  
            if( d >= 0 &&
3295  
            if( d >= 0 &&
3283  
                d <= (detail::to_number_limit<T>::max)() &&
3296  
                d <= (detail::to_number_limit<T>::max)() &&
3284  
                static_cast<T>(d) == d)
3297  
                static_cast<T>(d) == d)
3285  
            {
3298  
            {
3286  
                e = {};
3299  
                e = {};
3287  
                return static_cast<T>(d);
3300  
                return static_cast<T>(d);
3288  
            }
3301  
            }
3289  
            e = error::not_exact;
3302  
            e = error::not_exact;
3290  
        }
3303  
        }
3291  
        else
3304  
        else
3292  
        {
3305  
        {
3293  
            e = error::not_number;
3306  
            e = error::not_number;
3294  
        }
3307  
        }
3295  
        return T{};
3308  
        return T{};
3296  
    }
3309  
    }
3297  

3310  

3298  
    template<class T>
3311  
    template<class T>
3299  
    auto
3312  
    auto
3300  
    to_number(error& e) const noexcept ->
3313  
    to_number(error& e) const noexcept ->
3301  
        typename std::enable_if<
3314  
        typename std::enable_if<
3302  
            std::is_floating_point<
3315  
            std::is_floating_point<
3303  
                T>::value, T>::type
3316  
                T>::value, T>::type
3304  
    {
3317  
    {
3305  
        if(sca_.k == json::kind::int64)
3318  
        if(sca_.k == json::kind::int64)
3306  
        {
3319  
        {
3307  
            e = {};
3320  
            e = {};
3308  
            return static_cast<T>(sca_.i);
3321  
            return static_cast<T>(sca_.i);
3309  
        }
3322  
        }
3310  
        if(sca_.k == json::kind::uint64)
3323  
        if(sca_.k == json::kind::uint64)
3311  
        {
3324  
        {
3312  
            e = {};
3325  
            e = {};
3313  
            return static_cast<T>(sca_.u);
3326  
            return static_cast<T>(sca_.u);
3314  
        }
3327  
        }
3315  
        if(sca_.k == json::kind::double_)
3328  
        if(sca_.k == json::kind::double_)
3316  
        {
3329  
        {
3317  
            e = {};
3330  
            e = {};
3318  
            return static_cast<T>(sca_.d);
3331  
            return static_cast<T>(sca_.d);
3319  
        }
3332  
        }
3320  
        e = error::not_number;
3333  
        e = error::not_number;
3321  
        return {};
3334  
        return {};
3322  
    }
3335  
    }
3323  
};
3336  
};
3324  

3337  

3325  
// Make sure things are as big as we think they should be
3338  
// Make sure things are as big as we think they should be
3326  
#if BOOST_JSON_ARCH == 64
3339  
#if BOOST_JSON_ARCH == 64
3327  
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3340  
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3328  
#elif BOOST_JSON_ARCH == 32
3341  
#elif BOOST_JSON_ARCH == 32
3329  
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3342  
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3330  
#else
3343  
#else
3331  
# error Unknown architecture
3344  
# error Unknown architecture
3332  
#endif
3345  
#endif
3333  

3346  

3334  
//----------------------------------------------------------
3347  
//----------------------------------------------------------
3335  

3348  

3336  
/** A key/value pair.
3349  
/** A key/value pair.
3337  

3350  

3338  
    This is the type of element used by the @ref object container.
3351  
    This is the type of element used by the @ref object container.
3339  
*/
3352  
*/
3340  
class key_value_pair
3353  
class key_value_pair
3341  
{
3354  
{
3342  
#ifndef BOOST_JSON_DOCS
3355  
#ifndef BOOST_JSON_DOCS
3343  
    friend struct detail::access;
3356  
    friend struct detail::access;
3344  
    using access = detail::access;
3357  
    using access = detail::access;
3345  
#endif
3358  
#endif
3346  

3359  

3347  
    BOOST_JSON_DECL
3360  
    BOOST_JSON_DECL
3348  
    static char const empty_[1];
3361  
    static char const empty_[1];
3349  

3362  

3350  
    inline
3363  
    inline
3351  
    key_value_pair(
3364  
    key_value_pair(
3352  
        pilfered<json::value> k,
3365  
        pilfered<json::value> k,
3353  
        pilfered<json::value> v) noexcept;
3366  
        pilfered<json::value> v) noexcept;
3354  

3367  

3355  
public:
3368  
public:
3356  
    /** Assignment
3369  
    /** Assignment
3357  

3370  

3358  
        This type is not copy or move-assignable. The copy assignment operator
3371  
        This type is not copy or move-assignable. The copy assignment operator
3359  
        is deleted.
3372  
        is deleted.
3360  
    */
3373  
    */
3361  
    key_value_pair&
3374  
    key_value_pair&
3362  
    operator=(key_value_pair const&) = delete;
3375  
    operator=(key_value_pair const&) = delete;
3363  

3376  

3364  
    /** Destructor.
3377  
    /** Destructor.
3365  

3378  

3366  
        The value is destroyed and all internally allocated memory is freed.
3379  
        The value is destroyed and all internally allocated memory is freed.
3367  
    */
3380  
    */
3368  
    ~key_value_pair() noexcept
3381  
    ~key_value_pair() noexcept
3369  
    {
3382  
    {
3370  
        auto const& sp = value_.storage();
3383  
        auto const& sp = value_.storage();
3371  
        if(sp.is_not_shared_and_deallocate_is_trivial())
3384  
        if(sp.is_not_shared_and_deallocate_is_trivial())
3372  
            return;
3385  
            return;
3373  
        if(key_ == empty_)
3386  
        if(key_ == empty_)
3374  
            return;
3387  
            return;
3375  
        sp->deallocate(const_cast<char*>(key_),
3388  
        sp->deallocate(const_cast<char*>(key_),
3376  
            len_ + 1, alignof(char));
3389  
            len_ + 1, alignof(char));
3377  
    }
3390  
    }
3378  

3391  

3379  
    /** Constructors.
3392  
    /** Constructors.
3380  

3393  

3381  
        Construct a key/value pair.
3394  
        Construct a key/value pair.
3382  

3395  

3383  
        @li **(1)** uses a copy of the characters of `key`, and constructs the
3396  
        @li **(1)** uses a copy of the characters of `key`, and constructs the
3384  
            value as if by `value(std::forward<Args>(args)...)`.
3397  
            value as if by `value(std::forward<Args>(args)...)`.
3385  
        @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
3398  
        @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
3386  
        @li **(3)** equivalent to
3399  
        @li **(3)** equivalent to
3387  
            `key_value_pair(p.first, std::move(p.second), sp)`.
3400  
            `key_value_pair(p.first, std::move(p.second), sp)`.
3388  
        @li **(4)** equivalent to
3401  
        @li **(4)** equivalent to
3389  
            `key_value_pair(other.key(), other.value(), sp)`.
3402  
            `key_value_pair(other.key(), other.value(), sp)`.
3390  
        @li **(5)** equivalent to
3403  
        @li **(5)** equivalent to
3391  
            `key_value_pair(other.key(), other.value(), other.storage())`.
3404  
            `key_value_pair(other.key(), other.value(), other.storage())`.
3392  
        @li **(6)** the pair s constructed by acquiring ownership of the
3405  
        @li **(6)** the pair s constructed by acquiring ownership of the
3393  
            contents of `other` using move semantics.
3406  
            contents of `other` using move semantics.
3394  
        @li **(7)** the pair is constructed by acquiring ownership of the
3407  
        @li **(7)** the pair is constructed by acquiring ownership of the
3395  
            contents of `other` using pilfer semantics. This is more efficient
3408  
            contents of `other` using pilfer semantics. This is more efficient
3396  
            than move construction, when it is known that the moved-from object
3409  
            than move construction, when it is known that the moved-from object
3397  
            will be immediately destroyed afterwards.
3410  
            will be immediately destroyed afterwards.
3398  

3411  

3399  
        With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
3412  
        With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
3400  
        `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
3413  
        `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
3401  
        `other.storage()`. With **(1)** it uses whatever memory resource
3414  
        `other.storage()`. With **(1)** it uses whatever memory resource
3402  
        `value(std::forward<Args>(args)...)` would use. In any case the pair
3415  
        `value(std::forward<Args>(args)...)` would use. In any case the pair
3403  
        acquires shared ownership of its memory resource
3416  
        acquires shared ownership of its memory resource
3404  

3417  

3405  
        After **(6)** `other` holds an empty key, and a null value with its
3418  
        After **(6)** `other` holds an empty key, and a null value with its
3406  
        current storage pointer.
3419  
        current storage pointer.
3407  

3420  

3408  
        After **(7)** `other` is not in a usable state and may only be destroyed.
3421  
        After **(7)** `other` is not in a usable state and may only be destroyed.
3409  

3422  

3410  
        @par Complexity
3423  
        @par Complexity
3411  
        Constant.
3424  
        Constant.
3412  

3425  

3413  
        @par Exception Safety
3426  
        @par Exception Safety
3414  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
3427  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
3415  
        @param key The key string to use.
3428  
        @param key The key string to use.
3416  
        @param args Optional arguments forwarded to the @ref value constructor.
3429  
        @param args Optional arguments forwarded to the @ref value constructor.
3417  

3430  

3418  
        @throw boost::system::system_error The size of the key would exceed
3431  
        @throw boost::system::system_error The size of the key would exceed
3419  
               @ref string::max_size.
3432  
               @ref string::max_size.
3420  

3433  

3421  
        @see @ref pilfer,
3434  
        @see @ref pilfer,
3422  
             [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
3435  
             [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
3423  

3436  

3424  
        @{
3437  
        @{
3425  
    */
3438  
    */
3426  
    template<class... Args>
3439  
    template<class... Args>
3427  
    explicit
3440  
    explicit
3428  
    key_value_pair(
3441  
    key_value_pair(
3429  
        string_view key,
3442  
        string_view key,
3430  
        Args&&... args)
3443  
        Args&&... args)
3431  
        : value_(std::forward<Args>(args)...)
3444  
        : value_(std::forward<Args>(args)...)
3432  
    {
3445  
    {
3433  
        if(key.size() > string::max_size())
3446  
        if(key.size() > string::max_size())
3434  
        {
3447  
        {
3435  
            BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
3448  
            BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
3436  
            detail::throw_system_error( error::key_too_large, &loc );
3449  
            detail::throw_system_error( error::key_too_large, &loc );
3437  
        }
3450  
        }
3438  
        auto s = reinterpret_cast<
3451  
        auto s = reinterpret_cast<
3439  
            char*>(value_.storage()->
3452  
            char*>(value_.storage()->
3440  
                allocate(key.size() + 1, alignof(char)));
3453  
                allocate(key.size() + 1, alignof(char)));
3441  
        std::memcpy(s, key.data(), key.size());
3454  
        std::memcpy(s, key.data(), key.size());
3442  
        s[key.size()] = 0;
3455  
        s[key.size()] = 0;
3443  
        key_ = s;
3456  
        key_ = s;
3444  
        len_ = static_cast<
3457  
        len_ = static_cast<
3445  
            std::uint32_t>(key.size());
3458  
            std::uint32_t>(key.size());
3446  
    }
3459  
    }
3447  

3460  

3448  
    /** Overload
3461  
    /** Overload
3449  

3462  

3450  
        @param p A `std::pair` with the key string and @ref value to construct
3463  
        @param p A `std::pair` with the key string and @ref value to construct
3451  
               with.
3464  
               with.
3452  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
3465  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
3453  
               to use.
3466  
               to use.
3454  
    */
3467  
    */
3455  
    explicit
3468  
    explicit
3456  
    key_value_pair(
3469  
    key_value_pair(
3457  
        std::pair<
3470  
        std::pair<
3458  
            string_view,
3471  
            string_view,
3459  
            json::value> const& p,
3472  
            json::value> const& p,
3460  
        storage_ptr sp = {})
3473  
        storage_ptr sp = {})
3461  
        : key_value_pair(
3474  
        : key_value_pair(
3462  
            p.first,
3475  
            p.first,
3463  
            p.second,
3476  
            p.second,
3464  
            std::move(sp))
3477  
            std::move(sp))
3465  
    {
3478  
    {
3466  
    }
3479  
    }
3467  

3480  

3468  
    /// Overload
3481  
    /// Overload
3469  
    explicit
3482  
    explicit
3470  
    key_value_pair(
3483  
    key_value_pair(
3471  
        std::pair<
3484  
        std::pair<
3472  
            string_view,
3485  
            string_view,
3473  
            json::value>&& p,
3486  
            json::value>&& p,
3474  
        storage_ptr sp = {})
3487  
        storage_ptr sp = {})
3475  
        : key_value_pair(
3488  
        : key_value_pair(
3476  
            p.first,
3489  
            p.first,
3477  
            std::move(p).second,
3490  
            std::move(p).second,
3478  
            std::move(sp))
3491  
            std::move(sp))
3479  
    {
3492  
    {
3480  
    }
3493  
    }
3481  

3494  

3482  
    /** Overload
3495  
    /** Overload
3483  

3496  

3484  
        @param other Another key/value pair.
3497  
        @param other Another key/value pair.
3485  
        @param sp
3498  
        @param sp
3486  
    */
3499  
    */
3487  
    BOOST_JSON_DECL
3500  
    BOOST_JSON_DECL
3488  
    key_value_pair(
3501  
    key_value_pair(
3489  
        key_value_pair const& other,
3502  
        key_value_pair const& other,
3490  
        storage_ptr sp);
3503  
        storage_ptr sp);
3491  

3504  

3492  
    /// Overload
3505  
    /// Overload
3493  
    key_value_pair(
3506  
    key_value_pair(
3494  
        key_value_pair const& other)
3507  
        key_value_pair const& other)
3495  
        : key_value_pair(other,
3508  
        : key_value_pair(other,
3496  
            other.storage())
3509  
            other.storage())
3497  
    {
3510  
    {
3498  
    }
3511  
    }
3499  

3512  

3500  
    /// Overload
3513  
    /// Overload
3501  
    key_value_pair(
3514  
    key_value_pair(
3502  
        key_value_pair&& other) noexcept
3515  
        key_value_pair&& other) noexcept
3503  
        : value_(std::move(other.value_))
3516  
        : value_(std::move(other.value_))
3504  
        , key_(detail::exchange(
3517  
        , key_(detail::exchange(
3505  
            other.key_, empty_))
3518  
            other.key_, empty_))
3506  
        , len_(detail::exchange(
3519  
        , len_(detail::exchange(
3507  
            other.len_, 0))
3520  
            other.len_, 0))
3508  
    {
3521  
    {
3509  
    }
3522  
    }
3510  

3523  

3511  
    /// Overload
3524  
    /// Overload
3512  
    key_value_pair(
3525  
    key_value_pair(
3513  
        pilfered<key_value_pair> other) noexcept
3526  
        pilfered<key_value_pair> other) noexcept
3514  
        : value_(pilfer(other.get().value_))
3527  
        : value_(pilfer(other.get().value_))
3515  
        , key_(detail::exchange(
3528  
        , key_(detail::exchange(
3516  
            other.get().key_, empty_))
3529  
            other.get().key_, empty_))
3517  
        , len_(detail::exchange(
3530  
        , len_(detail::exchange(
3518  
            other.get().len_, 0))
3531  
            other.get().len_, 0))
3519  
    {
3532  
    {
3520  
    }
3533  
    }
3521  
    /// @}
3534  
    /// @}
3522  

3535  

3523  
    /** The associated memory resource.
3536  
    /** The associated memory resource.
3524  

3537  

3525  
        Returns a pointer to the memory resource used to construct the value.
3538  
        Returns a pointer to the memory resource used to construct the value.
3526  

3539  

3527  
        @par Complexity
3540  
        @par Complexity
3528  
        Constant.
3541  
        Constant.
3529  

3542  

3530  
        @par Exception Safety
3543  
        @par Exception Safety
3531  
        No-throw guarantee.
3544  
        No-throw guarantee.
3532  
    */
3545  
    */
3533  
    storage_ptr const&
3546  
    storage_ptr const&
3534  
    storage() const noexcept
3547  
    storage() const noexcept
3535  
    {
3548  
    {
3536  
        return value_.storage();
3549  
        return value_.storage();
3537  
    }
3550  
    }
3538  

3551  

3539  
    /** The pair's key.
3552  
    /** The pair's key.
3540  

3553  

3541  
        After construction, the key may not be modified.
3554  
        After construction, the key may not be modified.
3542  

3555  

3543  
        @par Complexity
3556  
        @par Complexity
3544  
        Constant.
3557  
        Constant.
3545  

3558  

3546  
        @par Exception Safety
3559  
        @par Exception Safety
3547  
        No-throw guarantee.
3560  
        No-throw guarantee.
3548  
    */
3561  
    */
3549  
    string_view const
3562  
    string_view const
3550  
    key() const noexcept
3563  
    key() const noexcept
3551  
    {
3564  
    {
3552  
        return { key_, len_ };
3565  
        return { key_, len_ };
3553  
    }
3566  
    }
3554  

3567  

3555  
    /** The pair's key as a null-terminated string.
3568  
    /** The pair's key as a null-terminated string.
3556  

3569  

3557  
        @par Complexity
3570  
        @par Complexity
3558  
        Constant.
3571  
        Constant.
3559  

3572  

3560  
        @par Exception Safety
3573  
        @par Exception Safety
3561  
        No-throw guarantee.
3574  
        No-throw guarantee.
3562  
    */
3575  
    */
3563  
    char const*
3576  
    char const*
3564  
    key_c_str() const noexcept
3577  
    key_c_str() const noexcept
3565  
    {
3578  
    {
3566  
        return key_;
3579  
        return key_;
3567  
    }
3580  
    }
3568  

3581  

3569  
    /** The pair's value.
3582  
    /** The pair's value.
3570  

3583  

3571  
        @par Complexity
3584  
        @par Complexity
3572  
        Constant.
3585  
        Constant.
3573  

3586  

3574  
        @par Exception Safety
3587  
        @par Exception Safety
3575  
        No-throw guarantee.
3588  
        No-throw guarantee.
3576  

3589  

3577  
        @{
3590  
        @{
3578  
    */
3591  
    */
3579  
    json::value const&
3592  
    json::value const&
3580  
    value() const& noexcept
3593  
    value() const& noexcept
3581  
    {
3594  
    {
3582  
        return value_;
3595  
        return value_;
3583  
    }
3596  
    }
3584  

3597  

3585  
    json::value&&
3598  
    json::value&&
3586  
    value() && noexcept
3599  
    value() && noexcept
3587  
    {
3600  
    {
3588  
        return std::move( value() );
3601  
        return std::move( value() );
3589  
    }
3602  
    }
3590  

3603  

3591  
    json::value&
3604  
    json::value&
3592  
    value() & noexcept
3605  
    value() & noexcept
3593  
    {
3606  
    {
3594  
        return value_;
3607  
        return value_;
3595  
    }
3608  
    }
3596  
    /// @}
3609  
    /// @}
3597  

3610  

3598  
private:
3611  
private:
3599  
    json::value value_;
3612  
    json::value value_;
3600  
    char const* key_;
3613  
    char const* key_;
3601  
    std::uint32_t len_;
3614  
    std::uint32_t len_;
3602  
    std::uint32_t next_;
3615  
    std::uint32_t next_;
3603  
};
3616  
};
3604  

3617  

3605  
//----------------------------------------------------------
3618  
//----------------------------------------------------------
3606  

3619  

3607  
#ifdef BOOST_JSON_DOCS
3620  
#ifdef BOOST_JSON_DOCS
3608  

3621  

3609  
/** Tuple-like element access.
3622  
/** Tuple-like element access.
3610  

3623  

3611  
    This overload of `get` permits the key and value of a @ref key_value_pair
3624  
    This overload of `get` permits the key and value of a @ref key_value_pair
3612  
    to be accessed by index. For example:
3625  
    to be accessed by index. For example:
3613  

3626  

3614  
    @code
3627  
    @code
3615  
    key_value_pair kvp("num", 42);
3628  
    key_value_pair kvp("num", 42);
3616  
    string_view key = get<0>(kvp);
3629  
    string_view key = get<0>(kvp);
3617  
    value& jv = get<1>(kvp);
3630  
    value& jv = get<1>(kvp);
3618  
    @endcode
3631  
    @endcode
3619  

3632  

3620  
    @par Structured Bindings
3633  
    @par Structured Bindings
3621  
    When using C++17 or greater, objects of type @ref key_value_pair may be
3634  
    When using C++17 or greater, objects of type @ref key_value_pair may be
3622  
    used to initialize structured bindings:
3635  
    used to initialize structured bindings:
3623  

3636  

3624  
    @code
3637  
    @code
3625  
    key_value_pair kvp("num", 42);
3638  
    key_value_pair kvp("num", 42);
3626  
    auto& [key, value] = kvp;
3639  
    auto& [key, value] = kvp;
3627  
    @endcode
3640  
    @endcode
3628  

3641  

3629  
    Depending on the value of `I`, the return type will be:
3642  
    Depending on the value of `I`, the return type will be:
3630  

3643  

3631  
    @li `string_view const` if `I == 0`, or
3644  
    @li `string_view const` if `I == 0`, or
3632  
    @li `value&`, `value const&`, or `value&&` if `I == 1`.
3645  
    @li `value&`, `value const&`, or `value&&` if `I == 1`.
3633  

3646  

3634  
    Using any other value for `I` is ill-formed.
3647  
    Using any other value for `I` is ill-formed.
3635  

3648  

3636  
    @par Constraints
3649  
    @par Constraints
3637  
    `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3650  
    `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3638  

3651  

3639  
    @tparam I The element index to access.
3652  
    @tparam I The element index to access.
3640  

3653  

3641  
    @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
3654  
    @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
3642  

3655  

3643  
    @param kvp The @ref key_value_pair object to access.
3656  
    @param kvp The @ref key_value_pair object to access.
3644  
*/
3657  
*/
3645  
template<
3658  
template<
3646  
    std::size_t I,
3659  
    std::size_t I,
3647  
    class T>
3660  
    class T>
3648  
__see_below__
3661  
__see_below__
3649  
get(T&& kvp) noexcept;
3662  
get(T&& kvp) noexcept;
3650  

3663  

3651  
#else
3664  
#else
3652  

3665  

3653  
template<std::size_t I>
3666  
template<std::size_t I>
3654  
auto
3667  
auto
3655  
get(key_value_pair const&) noexcept ->
3668  
get(key_value_pair const&) noexcept ->
3656  
    typename std::conditional<I == 0,
3669  
    typename std::conditional<I == 0,
3657  
        string_view const,
3670  
        string_view const,
3658  
        value const&>::type
3671  
        value const&>::type
3659  
{
3672  
{
3660  
    static_assert(I == 0,
3673  
    static_assert(I == 0,
3661  
        "key_value_pair index out of range");
3674  
        "key_value_pair index out of range");
3662  
}
3675  
}
3663  

3676  

3664  
template<std::size_t I>
3677  
template<std::size_t I>
3665  
auto
3678  
auto
3666  
get(key_value_pair&) noexcept ->
3679  
get(key_value_pair&) noexcept ->
3667  
    typename std::conditional<I == 0,
3680  
    typename std::conditional<I == 0,
3668  
        string_view const,
3681  
        string_view const,
3669  
        value&>::type
3682  
        value&>::type
3670  
{
3683  
{
3671  
    static_assert(I == 0,
3684  
    static_assert(I == 0,
3672  
        "key_value_pair index out of range");
3685  
        "key_value_pair index out of range");
3673  
}
3686  
}
3674  

3687  

3675  
template<std::size_t I>
3688  
template<std::size_t I>
3676  
auto
3689  
auto
3677  
get(key_value_pair&&) noexcept ->
3690  
get(key_value_pair&&) noexcept ->
3678  
    typename std::conditional<I == 0,
3691  
    typename std::conditional<I == 0,
3679  
        string_view const,
3692  
        string_view const,
3680  
        value&&>::type
3693  
        value&&>::type
3681  
{
3694  
{
3682  
    static_assert(I == 0,
3695  
    static_assert(I == 0,
3683  
        "key_value_pair index out of range");
3696  
        "key_value_pair index out of range");
3684  
}
3697  
}
3685  

3698  

3686  
/** Extracts a key_value_pair's key using tuple-like interface
3699  
/** Extracts a key_value_pair's key using tuple-like interface
3687  
*/
3700  
*/
3688  
template<>
3701  
template<>
3689  
inline
3702  
inline
3690  
string_view const
3703  
string_view const
3691  
get<0>(key_value_pair const& kvp) noexcept
3704  
get<0>(key_value_pair const& kvp) noexcept
3692  
{
3705  
{
3693  
    return kvp.key();
3706  
    return kvp.key();
3694  
}
3707  
}
3695  

3708  

3696  
/** Extracts a key_value_pair's key using tuple-like interface
3709  
/** Extracts a key_value_pair's key using tuple-like interface
3697  
*/
3710  
*/
3698  
template<>
3711  
template<>
3699  
inline
3712  
inline
3700  
string_view const
3713  
string_view const
3701  
get<0>(key_value_pair& kvp) noexcept
3714  
get<0>(key_value_pair& kvp) noexcept
3702  
{
3715  
{
3703  
    return kvp.key();
3716  
    return kvp.key();
3704  
}
3717  
}
3705  

3718  

3706  
/** Extracts a key_value_pair's key using tuple-like interface
3719  
/** Extracts a key_value_pair's key using tuple-like interface
3707  
*/
3720  
*/
3708  
template<>
3721  
template<>
3709  
inline
3722  
inline
3710  
string_view const
3723  
string_view const
3711  
get<0>(key_value_pair&& kvp) noexcept
3724  
get<0>(key_value_pair&& kvp) noexcept
3712  
{
3725  
{
3713  
    return kvp.key();
3726  
    return kvp.key();
3714  
}
3727  
}
3715  

3728  

3716  
/** Extracts a key_value_pair's value using tuple-like interface
3729  
/** Extracts a key_value_pair's value using tuple-like interface
3717  
*/
3730  
*/
3718  
template<>
3731  
template<>
3719  
inline
3732  
inline
3720  
value const&
3733  
value const&
3721  
get<1>(key_value_pair const& kvp) noexcept
3734  
get<1>(key_value_pair const& kvp) noexcept
3722  
{
3735  
{
3723  
    return kvp.value();
3736  
    return kvp.value();
3724  
}
3737  
}
3725  

3738  

3726  
/** Extracts a key_value_pair's value using tuple-like interface
3739  
/** Extracts a key_value_pair's value using tuple-like interface
3727  
*/
3740  
*/
3728  
template<>
3741  
template<>
3729  
inline
3742  
inline
3730  
value&
3743  
value&
3731  
get<1>(key_value_pair& kvp) noexcept
3744  
get<1>(key_value_pair& kvp) noexcept
3732  
{
3745  
{
3733  
    return kvp.value();
3746  
    return kvp.value();
3734  
}
3747  
}
3735  

3748  

3736  
/** Extracts a key_value_pair's value using tuple-like interface
3749  
/** Extracts a key_value_pair's value using tuple-like interface
3737  
*/
3750  
*/
3738  
template<>
3751  
template<>
3739  
inline
3752  
inline
3740  
value&&
3753  
value&&
3741  
get<1>(key_value_pair&& kvp) noexcept
3754  
get<1>(key_value_pair&& kvp) noexcept
3742  
{
3755  
{
3743  
    return std::move(kvp.value());
3756  
    return std::move(kvp.value());
3744  
}
3757  
}
3745  

3758  

3746  
#endif
3759  
#endif
3747  

3760  

3748  
} // namespace json
3761  
} // namespace json
3749  
} // namespace boost
3762  
} // namespace boost
3750  

3763  

3751  
#ifdef __clang__
3764  
#ifdef __clang__
3752  
# pragma clang diagnostic push
3765  
# pragma clang diagnostic push
3753  
# pragma clang diagnostic ignored "-Wmismatched-tags"
3766  
# pragma clang diagnostic ignored "-Wmismatched-tags"
3754  
#endif
3767  
#endif
3755  

3768  

3756  
#ifndef BOOST_JSON_DOCS
3769  
#ifndef BOOST_JSON_DOCS
3757  

3770  

3758  
namespace std {
3771  
namespace std {
3759  

3772  

3760  
/** Tuple-like size access for key_value_pair
3773  
/** Tuple-like size access for key_value_pair
3761  
*/
3774  
*/
3762  
template<>
3775  
template<>
3763  
struct tuple_size< ::boost::json::key_value_pair >
3776  
struct tuple_size< ::boost::json::key_value_pair >
3764  
    : std::integral_constant<std::size_t, 2>
3777  
    : std::integral_constant<std::size_t, 2>
3765  
{
3778  
{
3766  
};
3779  
};
3767  

3780  

3768  
/** Tuple-like access for the key type of key_value_pair
3781  
/** Tuple-like access for the key type of key_value_pair
3769  
*/
3782  
*/
3770  
template<>
3783  
template<>
3771  
struct tuple_element<0, ::boost::json::key_value_pair>
3784  
struct tuple_element<0, ::boost::json::key_value_pair>
3772  
{
3785  
{
3773  
    using type = ::boost::json::string_view const;
3786  
    using type = ::boost::json::string_view const;
3774  
};
3787  
};
3775  

3788  

3776  
/** Tuple-like access for the value type of key_value_pair
3789  
/** Tuple-like access for the value type of key_value_pair
3777  
*/
3790  
*/
3778  
template<>
3791  
template<>
3779  
struct tuple_element<1, ::boost::json::key_value_pair>
3792  
struct tuple_element<1, ::boost::json::key_value_pair>
3780  
{
3793  
{
3781  
    using type = ::boost::json::value&;
3794  
    using type = ::boost::json::value&;
3782  
};
3795  
};
3783  

3796  

3784  
/** Tuple-like access for the value type of key_value_pair
3797  
/** Tuple-like access for the value type of key_value_pair
3785  
*/
3798  
*/
3786  
template<>
3799  
template<>
3787  
struct tuple_element<1, ::boost::json::key_value_pair const>
3800  
struct tuple_element<1, ::boost::json::key_value_pair const>
3788  
{
3801  
{
3789  
    using type = ::boost::json::value const&;
3802  
    using type = ::boost::json::value const&;
3790  
};
3803  
};
3791  

3804  

3792  
} // std
3805  
} // std
3793  

3806  

3794  
#endif
3807  
#endif
3795  

3808  

3796  
// std::hash specialization
3809  
// std::hash specialization
3797  
#ifndef BOOST_JSON_DOCS
3810  
#ifndef BOOST_JSON_DOCS
3798  
namespace std {
3811  
namespace std {
3799  
template <>
3812  
template <>
3800  
struct hash< ::boost::json::value > {
3813  
struct hash< ::boost::json::value > {
3801  
    BOOST_JSON_DECL
3814  
    BOOST_JSON_DECL
3802  
    std::size_t
3815  
    std::size_t
3803  
    operator()(::boost::json::value const& jv) const noexcept;
3816  
    operator()(::boost::json::value const& jv) const noexcept;
3804  
};
3817  
};
3805  
} // std
3818  
} // std
3806  
#endif
3819  
#endif
3807  

3820  

3808  

3821  

3809  
#ifdef __clang__
3822  
#ifdef __clang__
3810  
# pragma clang diagnostic pop
3823  
# pragma clang diagnostic pop
3811  
#endif
3824  
#endif
3812  

3825  

3813  
// These are here because value, array,
3826  
// These are here because value, array,
3814  
// and object form cyclic references.
3827  
// and object form cyclic references.
3815  

3828  

3816  
#include <boost/json/detail/impl/array.hpp>
3829  
#include <boost/json/detail/impl/array.hpp>
3817  
#include <boost/json/impl/array.hpp>
3830  
#include <boost/json/impl/array.hpp>
3818  
#include <boost/json/impl/object.hpp>
3831  
#include <boost/json/impl/object.hpp>
3819  
#include <boost/json/impl/value.hpp>
3832  
#include <boost/json/impl/value.hpp>
3820  

3833  

3821  
// These must come after array and object
3834  
// These must come after array and object
3822  
#include <boost/json/impl/value_ref.hpp>
3835  
#include <boost/json/impl/value_ref.hpp>
3823  

3836  

3824  
#endif
3837  
#endif