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 -
#include <boost/core/detail/static_assert.hpp>
 
14  

13  

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

34  

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

37  

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

39  

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

41  

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

45  

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

55  

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

65  

67  
    struct init_iter;
66  
    struct init_iter;
68  

67  

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

72  

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

79  

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

86  

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

94  

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

103  

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

108  

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

112  

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

114  

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

117  

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

120  

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

126  

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

128  

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

130  

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

168  

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

176  

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

180  

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

183  

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

201  

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

204  

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

218  

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

220  

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

230  

232  
    /** Overload
231  
    /** Overload
233  

232  

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

241  

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

249  

251  
    /** Overload
250  
    /** Overload
252  

251  

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

271  

273  
    /** Overload
272  
    /** Overload
274  

273  

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

284  

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

293  

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

302  

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

311  

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

320  

322  
    /** Overload
321  
    /** Overload
323  

322  

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

333  

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

342  

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

351  

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

360  

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

369  

371  
    /** Overload
370  
    /** Overload
372  

371  

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

381  

383  
    /** Overload
382  
    /** Overload
384  

383  

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

393  

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

401  

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

408  

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

418  

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

428  

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

436  

438  
    /** Overload
437  
    /** Overload
439  

438  

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

445  

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

455  

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

465  

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

473  

475  
    /** Overload
474  
    /** Overload
476  

475  

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

482  

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

490  

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

498  

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

506  

508  
    /** Overload
507  
    /** Overload
509  

508  

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

516  

518  
    /** Overload
517  
    /** Overload
519  

518  

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

525  

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

531  

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

535  

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

541  

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

549  

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

555  

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

557  

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

559  

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

581  

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

587  

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

604  

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

607  

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

611  

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

613  

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

615  

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

621  

623  
    /** Overload
622  
    /** Overload
624  

623  

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

626  

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

632  

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

642  

644  
    /** Overload
643  
    /** Overload
645  

644  

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

651  

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

667  

669  
    /** Overload
668  
    /** Overload
670  

669  

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

694  

696  
    /** Overload
695  
    /** Overload
697  

696  

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

704  

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

711  

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

718  

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

725  

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

741  

743  
    /** Overload
742  
    /** Overload
744  

743  

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

751  

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

758  

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

765  

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

772  

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

788  

790  
    /** Overload
789  
    /** Overload
791  

790  

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

807  

809  
    /** Overload
808  
    /** Overload
810  

809  

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

814  

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

818  

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

822  

824  
    /** Overload
823  
    /** Overload
825  

824  

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

827  

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

833  

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

838  

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

843  

845  
    /** Overload
844  
    /** Overload
846  

845  

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

847  

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

851  

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

854  

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

859  

861  
    /** Overload
860  
    /** Overload
862  

861  

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

864  

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

870  

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

875  

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

878  

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

882  

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

887  

889  
    /** Overload
888  
    /** Overload
890  

889  

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

891  

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

895  

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

898  

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

903  

905  
    /** Overload
904  
    /** Overload
906  

905  

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

908  

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

914  

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

919  

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

922  

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

926  

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

932  

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

938  

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

940  

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

943  

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

946  

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

955  

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

957  

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

960  

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

963  

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

966  

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

975  

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

977  

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

980  

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

983  

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

986  

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

995  

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

997  

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

1000  

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

1003  

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

1006  

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

1015  

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

1017  

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

1020  

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

1023  

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

1026  

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

1035  

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

1037  

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

1041  

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

1044  

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

1047  

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

1053  

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

1055  

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

1059  

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

1062  

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

1065  

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

1071  

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

1073  

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

1077  

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

1080  

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

1083  

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

1089  

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

1091  

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

1095  

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

1103  

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

1106  

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

1109  

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

1115  

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

1117  

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

1121  

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

1129  

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

1132  

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

1135  

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

1138  

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

1147  

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

1153  

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

1155  

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

1159  

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

1162  

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

1173  

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

1175  

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

1177  

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

1179  

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

1182  

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

1191  

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

1193  

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

1195  

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

1197  

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

1200  

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

1209  

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

1211  

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

1213  

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

1215  

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

1218  

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

1227  

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

1229  

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

1231  

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

1233  

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

1236  

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

1245  

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

1247  

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

1249  

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

1251  

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

1254  

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

1263  

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

1265  

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

1267  

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

1269  

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

1272  

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

1281  

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

1283  

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

1285  

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

1287  

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

1290  

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

1299  

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

1301  

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

1303  

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

1305  

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

1308  

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

1317  

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

1319  

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

1322  

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

1325  

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

1337  

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

1339  

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

1342  

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

1345  

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

1357  

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

1359  

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

1362  

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

1365  

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

1378  

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

1380  

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

1382  

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

1385  

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

1393  

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

1396  

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

1399  

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

1409  

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

1418  

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

1420  

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

1423  

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

1431  

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

1434  

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

1437  

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

1447  

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

1456  

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

1458  

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

1461  

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

1469  

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

1472  

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

1475  

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

1485  

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

1494  

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

1496  

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

1499  

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

1507  

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

1510  

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

1513  

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

1523  

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

1532  

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

1534  

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

1537  

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

1545  

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

1548  

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

1551  

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

1561  

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

1570  

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

1572  

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

1575  

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

1583  

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

1586  

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

1589  

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

1599  

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

1608  

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

1610  

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

1613  

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

1621  

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

1624  

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

1627  

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

1637  

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

1646  

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

1648  

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

1650  

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

1653  

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

1666  

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

1671  

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

1674  

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

1678  

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

1680  

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

1682  

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

1684  

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

1703  

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

1720  

1722  
    /** Overload
1721  
    /** Overload
1723  

1722  

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

1740  

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

1742  

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

1745  

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

1759  

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

1764  

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

1767  

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

1770  

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

1789  

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

1792  

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

1798  

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

1800  

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

1803  

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

1806  

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

1815  

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

1817  

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

1820  

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

1823  

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

1832  

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

1834  

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

1836  

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

1839  

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

1847  

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

1852  

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

1855  

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

1858  

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

1864  

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

1869  

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

1871  

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

1874  

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

1882  

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

1887  

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

1890  

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

1893  

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

1899  

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

1904  

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

1906  

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

1909  

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

1917  

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

1922  

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

1925  

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

1928  

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

1934  

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

1939  

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

1941  

1943  
        If @ref is_int64() is `true`, the result contains a reference to **(1)**
1942  
        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
1943  
        or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1945  
        contains an `error_code`.
1944  
        contains an `error_code`.
1946  

1945  

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

1953  

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

1958  

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

1961  

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

1964  

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

1970  

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

1975  

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

1977  

1979  
        If @ref is_uint64() is `true`, the result contains a reference to **(1)**
1978  
        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
1979  
        or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1981  
        contains an `error_code`.
1980  
        contains an `error_code`.
1982  

1981  

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

1989  

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

1994  

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

1997  

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

2000  

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

2006  

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

2011  

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

2013  

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

2017  

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

2025  

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

2030  

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

2033  

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

2036  

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

2042  

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

2047  

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

2049  

2051  
        If @ref is_bool() is `true`, the result contains a reference to **(1)**
2050  
        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
2051  
        or a copy to **(2)** the underlying `bool`, otherwise it contains an
2053  
        `error_code`.
2052  
        `error_code`.
2054  

2053  

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

2061  

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

2066  

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

2069  

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

2072  

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

2078  

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

2083  

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

2085  

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

2088  

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

2096  

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

2101  

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

2104  

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

2111  

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

2113  

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

2115  

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

2118  

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

2121  

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

2123  

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

2126  

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

2129  

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

2138  

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

2145  

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

2151  

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

2153  

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

2156  

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

2159  

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

2161  

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

2164  

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

2167  

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

2176  

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

2183  

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

2189  

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

2191  

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

2194  

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

2197  

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

2199  

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

2202  

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

2205  

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

2214  

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

2221  

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

2227  

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

2229  

2231  
        If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
2230  
        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
2231  
        of **(2)** the underlying `std::int64_t`, otherwise throws an
2233  
        exception.
2232  
        exception.
2234  

2233  

2235  
        @note This function is the intended for direct access to the underlying
2234  
        @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
2235  
        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
2236  
        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`
2237  
        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
2238  
        has, and you only care about getting a `std::int64_t` number, consider
2240  
        using @ref to_number instead.
2239  
        using @ref to_number instead.
2241  

2240  

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

2243  

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

2245  

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

2248  

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

2251  

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

2257  

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

2263  

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

2265  

2267  
        If @ref is_uint64() is `true`, returns a reference to **(1)** or a
2266  
        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
2267  
        copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2269  
        exception.
2268  
        exception.
2270  

2269  

2271  
        @note This function is intended for direct access to the underlying
2270  
        @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
2271  
        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
2272  
        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`
2273  
        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
2274  
        has, and you only care about getting a `std::uint64_t` number, consider
2276  
        using @ref to_number instead.
2275  
        using @ref to_number instead.
2277  

2276  

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

2279  

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

2281  

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

2284  

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

2287  

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

2293  

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

2299  

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

2301  

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

2304  

2306  
        @note This function is intended for direct access to the underlying
2305  
        @note This function is intended for direct access to the underlying
2307  
        object, __if__ it has the type `double`. It does not convert the
2306  
        object, __if__ it has the type `double`. It does not convert the
2308  
        underlying object to type `double` even if a lossless conversion is
2307  
        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
2308  
        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
2309  
        care about getting a `double` number, consider using @ref to_number
2311  
        instead.
2310  
        instead.
2312  

2311  

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

2314  

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

2316  

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

2319  

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

2322  

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

2328  

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

2334  

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

2336  

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

2339  

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

2342  

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

2344  

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

2347  

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

2350  

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

2356  

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

2362  

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

2364  

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

2366  

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

2369  

2371  
        @par Preconditions
2370  
        @par Preconditions
2372  

2371  

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

2375  

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

2378  

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

2381  

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

2390  

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

2397  

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

2405  

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

2407  

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

2410  

2412  
        @par Preconditions
2411  
        @par Preconditions
2413  

2412  

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

2416  

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

2419  

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

2422  

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

2431  

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

2438  

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

2446  

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

2448  

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

2451  

2453  
        @par Preconditions
2452  
        @par Preconditions
2454  

2453  

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

2457  

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

2460  

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

2463  

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

2472  

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

2479  

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

2487  

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

2489  

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

2492  

2494  
        @par Preconditions
2493  
        @par Preconditions
2495  

2494  

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

2498  

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

2501  

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

2504  

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

2513  

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

2521  

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

2523  

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

2526  

2528  
        @par Preconditions
2527  
        @par Preconditions
2529  

2528  

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

2532  

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

2535  

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

2538  

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

2547  

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

2555  

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

2557  

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

2560  

2562  
        @par Preconditions
2561  
        @par Preconditions
2563  

2562  

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

2566  

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

2569  

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

2572  

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

2581  

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

2589  

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

2591  

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

2594  

2596  
        @par Preconditions
2595  
        @par Preconditions
2597  

2596  

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

2600  

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

2603  

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

2606  

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

2615  

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

2623  

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

2625  

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

2627  

2629  
        Returns `boost::system::result` containing a reference to the element
2628  
        Returns `boost::system::result` containing a reference to the element
2630  
        of the underlying ccontainer, if such element exists. If the underlying
2629  
        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
2630  
        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`.
2631  
        have a corresponding element the result contains an `error_code`.
2633  

2632  

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

2635  

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

2640  

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

2644  

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

2649  

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

2652  

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

2654  

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

2657  

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

2660  

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

2666  

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

2670  

2672  
    /** Overload
2671  
    /** Overload
2673  

2672  

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

2678  

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

2684  

2686  

2685  

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

2687  

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

2691  

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

2696  

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

2699  

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

2702  

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

2706  

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

2712  

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

2714  

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

2722  

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

2729  

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

2738  

2740  
    /** Overload
2739  
    /** Overload
2741  

2740  

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

2749  

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

2756  

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

2765  

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

2767  

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

2770  

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

2773  

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

2776  

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

2778  

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

2781  

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

2784  

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

2790  

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

2795  

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

2797  

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

2800  

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

2803  

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

2806  

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

2810  

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

2812  

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

2814  

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

2817  

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

2825  

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

2832  

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

2840  

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

2842  

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

2845  

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

2848  

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

2851  

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

2854  

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

2856  

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

2859  

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

2865  

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

2869  

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

2873  

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

2878  

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

2880  

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

2882  

2884  
        This function is used to insert or assign to a potentially nested
2883  
        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
2884  
        element of the value using a JSON Pointer string. The function may
2886  
        create intermediate elements corresponding to pointer segments.
2885  
        create intermediate elements corresponding to pointer segments.
2887  

2886  

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

2889  

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

2891  

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

2895  

2897  
        - if the containing value is an @ref array, and the token represents a
2896  
        - 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;
2897  
          past-the-end marker, then a `null` element is appended to the array;
2899  
          otherwise
2898  
          otherwise
2900  

2899  

2901  
        - if the containing value is an @ref array, and the token represents a
2900  
        - 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
2901  
          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
2902  
          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
2903  
          array is increased, so that the number can reference an element in the
2905  
          array; otherwise
2904  
          array; otherwise
2906  

2905  

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

2908  

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

2912  

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

2915  

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

2917  

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

2921  

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

2924  

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

2928  

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

2931  

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

2942  

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

2944  

2946  
        This function is used to insert or assign to a potentially nested
2945  
        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
2946  
        element of the value using a JSON Pointer string. The function may
2948  
        create intermediate elements corresponding to pointer segments.
2947  
        create intermediate elements corresponding to pointer segments.
2949  

2948  

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

2951  

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

2953  

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

2956  

2958  
        - if the containing value is an @ref array, and the token represents a
2957  
        - 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;
2958  
        past-the-end marker, then a `null` element is appended to the array;
2960  
        otherwise
2959  
        otherwise
2961  

2960  

2962  
        - if the containing value is an @ref array, and the token represents a
2961  
        - 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
2962  
        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
2963  
        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
2964  
        array is increased, so that the number can reference an element in the
2966  
        array; otherwise
2965  
        array; otherwise
2967  

2966  

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

2969  

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

2973  

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

2976  

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

2978  

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

2982  

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

2986  

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

2988  

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

2990  

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

2992  

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

2994  

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

2997  

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

3000  

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

3009  

3011  
    /** Overload
3010  
    /** Overload
3012  

3011  

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

3024  

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

3034  

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

3036  

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

3038  

3040  
        Two values are equal when they are the same kind and their referenced
3039  
        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
3040  
        values are equal, or when they are both integral types and their
3042  
        integral representations are equal.
3041  
        integral representations are equal.
3043  

3042  

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

3046  

3048  
        @par Exception Safety
3047  
        @par Exception Safety
3049  
        No-throw guarantee.
3048  
        No-throw guarantee.
3050  
    */
3049  
    */
3051  
    // inline friend speeds up overload resolution
3050  
    // inline friend speeds up overload resolution
3052  
    friend
3051  
    friend
3053  
    bool
3052  
    bool
3054  
    operator==(
3053  
    operator==(
3055  
        value const& lhs,
3054  
        value const& lhs,
3056  
        value const& rhs) noexcept
3055  
        value const& rhs) noexcept
3057  
    {
3056  
    {
3058  
        return lhs.equal(rhs);
3057  
        return lhs.equal(rhs);
3059  
    }
3058  
    }
3060  

3059  

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

3061  

3063  
        Two values are equal when they are the same kind and their referenced
3062  
        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
3063  
        values are equal, or when they are both integral types and their
3065  
        integral representations are equal.
3064  
        integral representations are equal.
3066  

3065  

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

3069  

3071  
        @par Exception Safety
3070  
        @par Exception Safety
3072  
        No-throw guarantee.
3071  
        No-throw guarantee.
3073  
    */
3072  
    */
3074  
    friend
3073  
    friend
3075  
    bool
3074  
    bool
3076  
    operator!=(
3075  
    operator!=(
3077  
        value const& lhs,
3076  
        value const& lhs,
3078  
        value const& rhs) noexcept
3077  
        value const& rhs) noexcept
3079  
    {
3078  
    {
3080  
        return ! (lhs == rhs);
3079  
        return ! (lhs == rhs);
3081  
    }
3080  
    }
3082  

3081  

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

3083  

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

3085  

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

3087  

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

3090  

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

3094  

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

3096  

3098  
        @param jv The value to serialize.
3097  
        @param jv The value to serialize.
3099  
    */
3098  
    */
3100  
    BOOST_JSON_DECL
3099  
    BOOST_JSON_DECL
3101  
    friend
3100  
    friend
3102  
    std::ostream&
3101  
    std::ostream&
3103  
    operator<<(
3102  
    operator<<(
3104  
        std::ostream& os,
3103  
        std::ostream& os,
3105  
        value const& jv);
3104  
        value const& jv);
3106  

3105  

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

3107  

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

3115  

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

3121  

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

3123  

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

3126  

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

3131  

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

3133  

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

3135  

3137  
        @see @ref parse.
3136  
        @see @ref parse.
3138  
    */
3137  
    */
3139  
    BOOST_JSON_DECL
3138  
    BOOST_JSON_DECL
3140  
    friend
3139  
    friend
3141  
    std::istream&
3140  
    std::istream&
3142  
    operator>>(
3141  
    operator>>(
3143  
        std::istream& is,
3142  
        std::istream& is,
3144  
        value& jv);
3143  
        value& jv);
3145  

3144  

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

3146  

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

3151  

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

3153  

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

3155  

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

3176  

3178  
private:
3177  
private:
3179  
    static
3178  
    static
3180  
    void
3179  
    void
3181  
    relocate(
3180  
    relocate(
3182  
        value* dest,
3181  
        value* dest,
3183  
        value const& src) noexcept
3182  
        value const& src) noexcept
3184  
    {
3183  
    {
3185  
        std::memcpy(
3184  
        std::memcpy(
3186  
            static_cast<void*>(dest),
3185  
            static_cast<void*>(dest),
3187  
            &src,
3186  
            &src,
3188  
            sizeof(src));
3187  
            sizeof(src));
3189  
    }
3188  
    }
3190  

3189  

3191  
    BOOST_JSON_DECL
3190  
    BOOST_JSON_DECL
3192  
    storage_ptr
3191  
    storage_ptr
3193  
    destroy() noexcept;
3192  
    destroy() noexcept;
3194  

3193  

3195  
    BOOST_JSON_DECL
3194  
    BOOST_JSON_DECL
3196  
    bool
3195  
    bool
3197  
    equal(value const& other) const noexcept;
3196  
    equal(value const& other) const noexcept;
3198  

3197  

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

3248  

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

3296  

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

3323  

3325  
// Make sure things are as big as we think they should be
3324  
// Make sure things are as big as we think they should be
3326  
#if BOOST_JSON_ARCH == 64
3325  
#if BOOST_JSON_ARCH == 64
3327 -
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3326 +
BOOST_STATIC_ASSERT(sizeof(value) == 24);
3328  
#elif BOOST_JSON_ARCH == 32
3327  
#elif BOOST_JSON_ARCH == 32
3329 -
BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3328 +
BOOST_STATIC_ASSERT(sizeof(value) == 16);
3330  
#else
3329  
#else
3331  
# error Unknown architecture
3330  
# error Unknown architecture
3332  
#endif
3331  
#endif
3333  

3332  

3334  
//----------------------------------------------------------
3333  
//----------------------------------------------------------
3335  

3334  

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

3336  

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

3345  

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

3348  

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

3353  

3355  
public:
3354  
public:
3356  
    /** Assignment
3355  
    /** Assignment
3357  

3356  

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

3362  

3364  
    /** Destructor.
3363  
    /** Destructor.
3365  

3364  

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

3377  

3379  
    /** Constructors.
3378  
    /** Constructors.
3380  

3379  

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

3381  

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

3397  

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

3403  

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

3406  

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

3408  

3410  
        @par Complexity
3409  
        @par Complexity
3411  
        Constant.
3410  
        Constant.
3412  

3411  

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

3416  

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

3419  

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

3422  

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

3446  

3448  
    /** Overload
3447  
    /** Overload
3449  

3448  

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

3466  

3468  
    /// Overload
3467  
    /// Overload
3469  
    explicit
3468  
    explicit
3470  
    key_value_pair(
3469  
    key_value_pair(
3471  
        std::pair<
3470  
        std::pair<
3472  
            string_view,
3471  
            string_view,
3473  
            json::value>&& p,
3472  
            json::value>&& p,
3474  
        storage_ptr sp = {})
3473  
        storage_ptr sp = {})
3475  
        : key_value_pair(
3474  
        : key_value_pair(
3476  
            p.first,
3475  
            p.first,
3477  
            std::move(p).second,
3476  
            std::move(p).second,
3478  
            std::move(sp))
3477  
            std::move(sp))
3479  
    {
3478  
    {
3480  
    }
3479  
    }
3481  

3480  

3482  
    /** Overload
3481  
    /** Overload
3483  

3482  

3484  
        @param other Another key/value pair.
3483  
        @param other Another key/value pair.
3485  
        @param sp
3484  
        @param sp
3486  
    */
3485  
    */
3487  
    BOOST_JSON_DECL
3486  
    BOOST_JSON_DECL
3488  
    key_value_pair(
3487  
    key_value_pair(
3489  
        key_value_pair const& other,
3488  
        key_value_pair const& other,
3490  
        storage_ptr sp);
3489  
        storage_ptr sp);
3491  

3490  

3492  
    /// Overload
3491  
    /// Overload
3493  
    key_value_pair(
3492  
    key_value_pair(
3494  
        key_value_pair const& other)
3493  
        key_value_pair const& other)
3495  
        : key_value_pair(other,
3494  
        : key_value_pair(other,
3496  
            other.storage())
3495  
            other.storage())
3497  
    {
3496  
    {
3498  
    }
3497  
    }
3499  

3498  

3500  
    /// Overload
3499  
    /// Overload
3501  
    key_value_pair(
3500  
    key_value_pair(
3502  
        key_value_pair&& other) noexcept
3501  
        key_value_pair&& other) noexcept
3503  
        : value_(std::move(other.value_))
3502  
        : value_(std::move(other.value_))
3504  
        , key_(detail::exchange(
3503  
        , key_(detail::exchange(
3505  
            other.key_, empty_))
3504  
            other.key_, empty_))
3506  
        , len_(detail::exchange(
3505  
        , len_(detail::exchange(
3507  
            other.len_, 0))
3506  
            other.len_, 0))
3508  
    {
3507  
    {
3509  
    }
3508  
    }
3510  

3509  

3511  
    /// Overload
3510  
    /// Overload
3512  
    key_value_pair(
3511  
    key_value_pair(
3513  
        pilfered<key_value_pair> other) noexcept
3512  
        pilfered<key_value_pair> other) noexcept
3514  
        : value_(pilfer(other.get().value_))
3513  
        : value_(pilfer(other.get().value_))
3515  
        , key_(detail::exchange(
3514  
        , key_(detail::exchange(
3516  
            other.get().key_, empty_))
3515  
            other.get().key_, empty_))
3517  
        , len_(detail::exchange(
3516  
        , len_(detail::exchange(
3518  
            other.get().len_, 0))
3517  
            other.get().len_, 0))
3519  
    {
3518  
    {
3520  
    }
3519  
    }
3521  
    /// @}
3520  
    /// @}
3522  

3521  

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

3523  

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

3525  

3527  
        @par Complexity
3526  
        @par Complexity
3528  
        Constant.
3527  
        Constant.
3529  

3528  

3530  
        @par Exception Safety
3529  
        @par Exception Safety
3531  
        No-throw guarantee.
3530  
        No-throw guarantee.
3532  
    */
3531  
    */
3533  
    storage_ptr const&
3532  
    storage_ptr const&
3534  
    storage() const noexcept
3533  
    storage() const noexcept
3535  
    {
3534  
    {
3536  
        return value_.storage();
3535  
        return value_.storage();
3537  
    }
3536  
    }
3538  

3537  

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

3539  

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

3541  

3543  
        @par Complexity
3542  
        @par Complexity
3544  
        Constant.
3543  
        Constant.
3545  

3544  

3546  
        @par Exception Safety
3545  
        @par Exception Safety
3547  
        No-throw guarantee.
3546  
        No-throw guarantee.
3548  
    */
3547  
    */
3549  
    string_view const
3548  
    string_view const
3550  
    key() const noexcept
3549  
    key() const noexcept
3551  
    {
3550  
    {
3552  
        return { key_, len_ };
3551  
        return { key_, len_ };
3553  
    }
3552  
    }
3554  

3553  

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

3555  

3557  
        @par Complexity
3556  
        @par Complexity
3558  
        Constant.
3557  
        Constant.
3559  

3558  

3560  
        @par Exception Safety
3559  
        @par Exception Safety
3561  
        No-throw guarantee.
3560  
        No-throw guarantee.
3562  
    */
3561  
    */
3563  
    char const*
3562  
    char const*
3564  
    key_c_str() const noexcept
3563  
    key_c_str() const noexcept
3565  
    {
3564  
    {
3566  
        return key_;
3565  
        return key_;
3567  
    }
3566  
    }
3568  

3567  

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

3569  

3571  
        @par Complexity
3570  
        @par Complexity
3572  
        Constant.
3571  
        Constant.
3573  

3572  

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

3575  

3577  
        @{
3576  
        @{
3578  
    */
3577  
    */
3579  
    json::value const&
3578  
    json::value const&
3580  
    value() const& noexcept
3579  
    value() const& noexcept
3581  
    {
3580  
    {
3582  
        return value_;
3581  
        return value_;
3583  
    }
3582  
    }
3584  

3583  

3585  
    json::value&&
3584  
    json::value&&
3586  
    value() && noexcept
3585  
    value() && noexcept
3587  
    {
3586  
    {
3588  
        return std::move( value() );
3587  
        return std::move( value() );
3589  
    }
3588  
    }
3590  

3589  

3591  
    json::value&
3590  
    json::value&
3592  
    value() & noexcept
3591  
    value() & noexcept
3593  
    {
3592  
    {
3594  
        return value_;
3593  
        return value_;
3595  
    }
3594  
    }
3596  
    /// @}
3595  
    /// @}
3597  

3596  

3598  
private:
3597  
private:
3599  
    json::value value_;
3598  
    json::value value_;
3600  
    char const* key_;
3599  
    char const* key_;
3601  
    std::uint32_t len_;
3600  
    std::uint32_t len_;
3602  
    std::uint32_t next_;
3601  
    std::uint32_t next_;
3603  
};
3602  
};
3604  

3603  

3605  
//----------------------------------------------------------
3604  
//----------------------------------------------------------
3606  

3605  

3607  
#ifdef BOOST_JSON_DOCS
3606  
#ifdef BOOST_JSON_DOCS
3608  

3607  

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

3609  

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

3612  

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

3618  

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

3622  

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

3627  

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

3629  

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

3632  

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

3634  

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

3637  

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

3639  

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

3641  

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

3649  

3651  
#else
3650  
#else
3652  

3651  

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

3662  

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

3673  

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

3684  

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

3694  

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

3704  

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

3714  

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

3724  

3726  
/** Extracts a key_value_pair's value using tuple-like interface
3725  
/** Extracts a key_value_pair's value using tuple-like interface
3727  
*/
3726  
*/
3728  
template<>
3727  
template<>
3729  
inline
3728  
inline
3730  
value&
3729  
value&
3731  
get<1>(key_value_pair& kvp) noexcept
3730  
get<1>(key_value_pair& kvp) noexcept
3732  
{
3731  
{
3733  
    return kvp.value();
3732  
    return kvp.value();
3734  
}
3733  
}
3735  

3734  

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

3744  

3746  
#endif
3745  
#endif
3747  

3746  

3748  
} // namespace json
3747  
} // namespace json
3749  
} // namespace boost
3748  
} // namespace boost
3750  

3749  

3751  
#ifdef __clang__
3750  
#ifdef __clang__
3752  
# pragma clang diagnostic push
3751  
# pragma clang diagnostic push
3753  
# pragma clang diagnostic ignored "-Wmismatched-tags"
3752  
# pragma clang diagnostic ignored "-Wmismatched-tags"
3754  
#endif
3753  
#endif
3755  

3754  

3756  
#ifndef BOOST_JSON_DOCS
3755  
#ifndef BOOST_JSON_DOCS
3757  

3756  

3758  
namespace std {
3757  
namespace std {
3759  

3758  

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

3766  

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

3774  

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

3782  

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

3790  

3792  
} // std
3791  
} // std
3793  

3792  

3794  
#endif
3793  
#endif
3795  

3794  

3796  
// std::hash specialization
3795  
// std::hash specialization
3797  
#ifndef BOOST_JSON_DOCS
3796  
#ifndef BOOST_JSON_DOCS
3798  
namespace std {
3797  
namespace std {
3799  
template <>
3798  
template <>
3800  
struct hash< ::boost::json::value > {
3799  
struct hash< ::boost::json::value > {
3801  
    BOOST_JSON_DECL
3800  
    BOOST_JSON_DECL
3802  
    std::size_t
3801  
    std::size_t
3803  
    operator()(::boost::json::value const& jv) const noexcept;
3802  
    operator()(::boost::json::value const& jv) const noexcept;
3804  
};
3803  
};
3805  
} // std
3804  
} // std
3806  
#endif
3805  
#endif
3807  

3806  

3808  

3807  

3809  
#ifdef __clang__
3808  
#ifdef __clang__
3810  
# pragma clang diagnostic pop
3809  
# pragma clang diagnostic pop
3811  
#endif
3810  
#endif
3812  

3811  

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

3814  

3816  
#include <boost/json/detail/impl/array.hpp>
3815  
#include <boost/json/detail/impl/array.hpp>
3817  
#include <boost/json/impl/array.hpp>
3816  
#include <boost/json/impl/array.hpp>
3818  
#include <boost/json/impl/object.hpp>
3817  
#include <boost/json/impl/object.hpp>
3819  
#include <boost/json/impl/value.hpp>
3818  
#include <boost/json/impl/value.hpp>
3820  

3819  

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

3822  

3824  
#endif
3823  
#endif