98.85% Lines (516/522) 99.28% Functions (138/139)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) 3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4   // 4   //
5   // Distributed under the Boost Software License, Version 1.0. (See accompanying 5   // Distributed under the Boost Software License, Version 1.0. (See accompanying
6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7   // 7   //
8   // Official repository: https://github.com/boostorg/json 8   // Official repository: https://github.com/boostorg/json
9   // 9   //
10   10  
11   #ifndef BOOST_JSON_VALUE_HPP 11   #ifndef BOOST_JSON_VALUE_HPP
12   #define BOOST_JSON_VALUE_HPP 12   #define BOOST_JSON_VALUE_HPP
13   13  
14   #include <boost/core/detail/static_assert.hpp> 14   #include <boost/core/detail/static_assert.hpp>
15   #include <boost/json/detail/config.hpp> 15   #include <boost/json/detail/config.hpp>
16   #include <boost/json/array.hpp> 16   #include <boost/json/array.hpp>
17   #include <boost/json/kind.hpp> 17   #include <boost/json/kind.hpp>
18   #include <boost/json/object.hpp> 18   #include <boost/json/object.hpp>
19   #include <boost/json/pilfer.hpp> 19   #include <boost/json/pilfer.hpp>
20   #include <boost/json/set_pointer_options.hpp> 20   #include <boost/json/set_pointer_options.hpp>
21   #include <boost/json/storage_ptr.hpp> 21   #include <boost/json/storage_ptr.hpp>
22   #include <boost/json/string.hpp> 22   #include <boost/json/string.hpp>
23   #include <boost/json/string_view.hpp> 23   #include <boost/json/string_view.hpp>
24   #include <boost/json/value_ref.hpp> 24   #include <boost/json/value_ref.hpp>
25   #include <boost/json/detail/except.hpp> 25   #include <boost/json/detail/except.hpp>
26   #include <boost/json/detail/value.hpp> 26   #include <boost/json/detail/value.hpp>
27   #include <cstdlib> 27   #include <cstdlib>
28   #include <cstring> 28   #include <cstring>
29   #include <initializer_list> 29   #include <initializer_list>
30   #include <iosfwd> 30   #include <iosfwd>
31   #include <limits> 31   #include <limits>
32   #include <new> 32   #include <new>
33   #include <type_traits> 33   #include <type_traits>
34   #include <utility> 34   #include <utility>
35   35  
36   namespace boost { 36   namespace boost {
37   namespace json { 37   namespace json {
38   38  
39   //---------------------------------------------------------- 39   //----------------------------------------------------------
40   40  
41   /** The type used to represent any JSON value 41   /** The type used to represent any JSON value
42   42  
43   This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular) 43   This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular)
44   type which works like a variant of the basic JSON data types: array, 44   type which works like a variant of the basic JSON data types: array,
45   object, string, number, boolean, and null. 45   object, string, number, boolean, and null.
46   46  
47   @par Thread Safety 47   @par Thread Safety
48   Distinct instances may be accessed concurrently. Non-const member 48   Distinct instances may be accessed concurrently. Non-const member
49   functions of a shared instance may not be called concurrently with any 49   functions of a shared instance may not be called concurrently with any
50   other member functions of that instance. 50   other member functions of that instance.
51   */ 51   */
52   class value 52   class value
53   { 53   {
54   #ifndef BOOST_JSON_DOCS 54   #ifndef BOOST_JSON_DOCS
55   using scalar = detail::scalar; 55   using scalar = detail::scalar;
56   56  
57   union 57   union
58   { 58   {
59   storage_ptr sp_; // must come first 59   storage_ptr sp_; // must come first
60   array arr_; 60   array arr_;
61   object obj_; 61   object obj_;
62   string str_; 62   string str_;
63   scalar sca_; 63   scalar sca_;
64   }; 64   };
65   #endif 65   #endif
66   66  
67   struct init_iter; 67   struct init_iter;
68   68  
69   #ifndef BOOST_JSON_DOCS 69   #ifndef BOOST_JSON_DOCS
70   // VFALCO doc toolchain incorrectly treats this as public 70   // VFALCO doc toolchain incorrectly treats this as public
71   friend struct detail::access; 71   friend struct detail::access;
72   #endif 72   #endif
73   73  
74   explicit 74   explicit
HITCBC 75   2120 value( 75   2120 value(
76   detail::unchecked_array&& ua) 76   detail::unchecked_array&& ua)
HITCBC 77   2120 : arr_(std::move(ua)) 77   2120 : arr_(std::move(ua))
78   { 78   {
HITCBC 79   2082 } 79   2082 }
80   80  
81   explicit 81   explicit
HITCBC 82   34879 value( 82   34879 value(
83   detail::unchecked_object&& uo) 83   detail::unchecked_object&& uo)
HITCBC 84   34879 : obj_(std::move(uo)) 84   34879 : obj_(std::move(uo))
85   { 85   {
HITCBC 86   34840 } 86   34840 }
87   87  
HITCBC 88   30296 value( 88   30296 value(
89   detail::key_t const&, 89   detail::key_t const&,
90   string_view s, 90   string_view s,
91   storage_ptr sp) 91   storage_ptr sp)
HITCBC 92   30296 : str_(detail::key_t{}, s, std::move(sp)) 92   30296 : str_(detail::key_t{}, s, std::move(sp))
93   { 93   {
HITCBC 94   30236 } 94   30236 }
95   95  
HITCBC 96   8060 value( 96   8060 value(
97   detail::key_t const&, 97   detail::key_t const&,
98   string_view s1, 98   string_view s1,
99   string_view s2, 99   string_view s2,
100   storage_ptr sp) 100   storage_ptr sp)
HITCBC 101   8060 : str_(detail::key_t{}, s1, s2, std::move(sp)) 101   8060 : str_(detail::key_t{}, s1, s2, std::move(sp))
102   { 102   {
HITCBC 103   8060 } 103   8060 }
104   104  
HITCBC 105   6707 inline bool is_scalar() const noexcept 105   6707 inline bool is_scalar() const noexcept
106   { 106   {
HITCBC 107   6707 return sca_.k < json::kind::string; 107   6707 return sca_.k < json::kind::string;
108   } 108   }
109   109  
110   public: 110   public:
111   /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator) 111   /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
112   using allocator_type = container::pmr::polymorphic_allocator<value>; 112   using allocator_type = container::pmr::polymorphic_allocator<value>;
113   113  
114   /** Destructor. 114   /** Destructor.
115   115  
116   The value and all of its contents are destroyed. Any dynamically 116   The value and all of its contents are destroyed. Any dynamically
117   allocated memory that was allocated internally is freed. 117   allocated memory that was allocated internally is freed.
118   118  
119   @par Complexity 119   @par Complexity
120   Constant, or linear in size for array or object. 120   Constant, or linear in size for array or object.
121   121  
122   @par Exception Safety 122   @par Exception Safety
123   No-throw guarantee. 123   No-throw guarantee.
124   */ 124   */
125   BOOST_JSON_DECL 125   BOOST_JSON_DECL
126   ~value() noexcept; 126   ~value() noexcept;
127   127  
128   /** Constructors. 128   /** Constructors.
129   129  
130   Construct a new `value`. 130   Construct a new `value`.
131   131  
132   @li **(1)**--**(3)** the constructed value is null. 132   @li **(1)**--**(3)** the constructed value is null.
133   @li **(4)** the constructed value contains a copy of `b`. 133   @li **(4)** the constructed value contains a copy of `b`.
134   @li **(5)**--**(9)** the constructed value contains a copy of `i`. 134   @li **(5)**--**(9)** the constructed value contains a copy of `i`.
135   @li **(10)**--**(14)** the constructed value contains a copy of `u`. 135   @li **(10)**--**(14)** the constructed value contains a copy of `u`.
136   @li **(15)** the constructed value contains a copy of `d`. 136   @li **(15)** the constructed value contains a copy of `d`.
137   @li **(16)**, **(19)** the constructed value contains a copy of the 137   @li **(16)**, **(19)** the constructed value contains a copy of the
138   string `s`. 138   string `s`.
139   @li **(17)** the constructed value contains a copy of the 139   @li **(17)** the constructed value contains a copy of the
140   null-terminated string `s`. 140   null-terminated string `s`.
141   @li **(18)** the constructed value takes ownership of `s`'s storage. 141   @li **(18)** the constructed value takes ownership of `s`'s storage.
142   @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise 142   @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise
143   equivalent to **(19)**. 143   equivalent to **(19)**.
144   @li **(21)** the constructed value contains an empty string. 144   @li **(21)** the constructed value contains an empty string.
145   @li **(22)** the constructed value takes ownership of `arr`'s storage. 145   @li **(22)** the constructed value takes ownership of `arr`'s storage.
146   @li **(23)** the constructed value contains an element-wise copy of the 146   @li **(23)** the constructed value contains an element-wise copy of the
147   array `arr`. 147   array `arr`.
148   @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**, 148   @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**,
149   otherwise equivalent to **(23)**. 149   otherwise equivalent to **(23)**.
150   @li **(25)** the constructed value contains an empty array. 150   @li **(25)** the constructed value contains an empty array.
151   @li **(26)** the constructed value takes ownership of `obj`'s storage. 151   @li **(26)** the constructed value takes ownership of `obj`'s storage.
152   @li **(27)** the constructed value contains an element-wise copy of the 152   @li **(27)** the constructed value contains an element-wise copy of the
153   object `obj`. 153   object `obj`.
154   @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**, 154   @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**,
155   otherwise equivalent to **(27)**. 155   otherwise equivalent to **(27)**.
156   @li **(29)** the constructed value contains an empty object. 156   @li **(29)** the constructed value contains an empty object.
157   @li **(30)** the constructed value's contents are formed by 157   @li **(30)** the constructed value's contents are formed by
158   constructing from `init` and `sp` (see \<\<initializer_lists\>\>). 158   constructing from `init` and `sp` (see \<\<initializer_lists\>\>).
159   @li **(31)**, **(32)** the constructed value contains a copy of the 159   @li **(31)**, **(32)** the constructed value contains a copy of the
160   contents of `other`. 160   contents of `other`.
161   @li **(33)** the constructed value acquires ownership of the contents 161   @li **(33)** the constructed value acquires ownership of the contents
162   of `other`. 162   of `other`.
163   @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`; 163   @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`;
164   otherwise equivalent to **(32)**. 164   otherwise equivalent to **(32)**.
165   @li **(35)** the constructed value acquires ownership of the contents 165   @li **(35)** the constructed value acquires ownership of the contents
166   of `other` using pilfer semantics. This is more efficient than move 166   of `other` using pilfer semantics. This is more efficient than move
167   construction, when it is known that the moved-from object will be 167   construction, when it is known that the moved-from object will be
168   immediately destroyed afterwards. 168   immediately destroyed afterwards.
169   169  
170   With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**, 170   With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**,
171   {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value 171   {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value
172   uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**, 172   uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**,
173   {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of 173   {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of
174   the argument (`s`, `arr`, obj`, or `value`). In either case the value 174   the argument (`s`, `arr`, obj`, or `value`). In either case the value
175   will share the ownership of the memory resource. With **(1)** 175   will share the ownership of the memory resource. With **(1)**
176   it uses the \<\<default_memory_resource, default memory resource\>\>. 176   it uses the \<\<default_memory_resource, default memory resource\>\>.
177   177  
178   After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves 178   After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves
179   as if newly constructed with its current storage pointer (i.e. becomes 179   as if newly constructed with its current storage pointer (i.e. becomes
180   an empty string, array, object, or null value). 180   an empty string, array, object, or null value).
181   181  
182   After **(35)** `other` is not in a usable state and may only be 182   After **(35)** `other` is not in a usable state and may only be
183   destroyed. 183   destroyed.
184   184  
185   @par Complexity 185   @par Complexity
186   @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**, 186   @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
187   {sp} **(26)**, **(29)**, **(33)**, **(35)** constant. 187   {sp} **(26)**, **(29)**, **(33)**, **(35)** constant.
188   @li **(16)**, **(19)** linear in `s.size()`. 188   @li **(16)**, **(19)** linear in `s.size()`.
189   @li **(17)** linear in `std::strlen(s)`. 189   @li **(17)** linear in `std::strlen(s)`.
190   @li **(20)** if `*s.storage() == *sp` constant, otherwise linear 190   @li **(20)** if `*s.storage() == *sp` constant, otherwise linear
191   in `s.size()`. 191   in `s.size()`.
192   @li **(23)** linear in `arr.size()`. 192   @li **(23)** linear in `arr.size()`.
193   @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear 193   @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear
194   in `arr.size()`. 194   in `arr.size()`.
195   @li **(27)** linear in `obj.size()`. 195   @li **(27)** linear in `obj.size()`.
196   @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear 196   @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear
197   in `obj.size()`. 197   in `obj.size()`.
198   @li **(30)** linear in `init.size()`. 198   @li **(30)** linear in `init.size()`.
199   @li **(31)**, **(32)** linear in the size of `other`. 199   @li **(31)**, **(32)** linear in the size of `other`.
200   @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in 200   @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in
201   the size of `other`. 201   the size of `other`.
202   202  
203   The size of `other` is either the size of the underlying container 203   The size of `other` is either the size of the underlying container
204   (if there is one), or can be considered to be 1. 204   (if there is one), or can be considered to be 1.
205   205  
206   @par Exception Safety 206   @par Exception Safety
207   @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**, 207   @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
208   **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee. 208   **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee.
209   @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**, 209   @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**,
210   **(30)**--**(32)** strong guarantee. 210   **(30)**--**(32)** strong guarantee.
211   @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise 211   @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise
212   strong guarantee. 212   strong guarantee.
213   @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise 213   @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise
214   strong guarantee. 214   strong guarantee.
215   @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise 215   @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise
216   strong guarantee. 216   strong guarantee.
217   @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise 217   @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise
218   strong guarantee. 218   strong guarantee.
219   219  
220   Calls to `memory_resource::allocate` may throw. 220   Calls to `memory_resource::allocate` may throw.
221   221  
222   @see @ref pilfer, 222   @see @ref pilfer,
223   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html). 223   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
224   // 224   //
225   @{ 225   @{
226   */ 226   */
HITCBC 227   211 value() noexcept 227   211 value() noexcept
HITCBC 228   211 : sca_() 228   211 : sca_()
229   { 229   {
HITCBC 230   211 } 230   211 }
231   231  
232   /** Overload 232   /** Overload
233   233  
234   @param sp A pointer to the @ref boost::container::pmr::memory_resource 234   @param sp A pointer to the @ref boost::container::pmr::memory_resource
235   to use. 235   to use.
236   */ 236   */
237   explicit 237   explicit
HITCBC 238   7138 value(storage_ptr sp) noexcept 238   7138 value(storage_ptr sp) noexcept
HITCBC 239   7138 : sca_(std::move(sp)) 239   7138 : sca_(std::move(sp))
240   { 240   {
HITCBC 241   7138 } 241   7138 }
242   242  
243   /// Overload 243   /// Overload
HITCBC 244   9679 value( 244   9679 value(
245   std::nullptr_t, 245   std::nullptr_t,
246   storage_ptr sp = {}) noexcept 246   storage_ptr sp = {}) noexcept
HITCBC 247   9679 : sca_(std::move(sp)) 247   9679 : sca_(std::move(sp))
248   { 248   {
HITCBC 249   9679 } 249   9679 }
250   250  
251   /** Overload 251   /** Overload
252   252  
253   @param b The boolean to construct with. 253   @param b The boolean to construct with.
254   @param sp 254   @param sp
255   */ 255   */
256   #ifdef BOOST_JSON_DOCS 256   #ifdef BOOST_JSON_DOCS
257   value( 257   value(
258   bool b, 258   bool b,
259   storage_ptr sp = {}) noexcept; 259   storage_ptr sp = {}) noexcept;
260   #else 260   #else
261   template<class T 261   template<class T
262   ,class = typename std::enable_if< 262   ,class = typename std::enable_if<
263   std::is_same<T, bool>::value>::type 263   std::is_same<T, bool>::value>::type
264   > 264   >
HITCBC 265   776 value( 265   776 value(
266   T b, 266   T b,
267   storage_ptr sp = {}) noexcept 267   storage_ptr sp = {}) noexcept
HITCBC 268   776 : sca_(b, std::move(sp)) 268   776 : sca_(b, std::move(sp))
269   { 269   {
HITCBC 270   776 } 270   776 }
271   #endif 271   #endif
272   272  
273   /** Overload 273   /** Overload
274   274  
275   @param i The number to construct with. 275   @param i The number to construct with.
276   @param sp 276   @param sp
277   */ 277   */
HITCBC 278   3 value( 278   3 value(
279   signed char i, 279   signed char i,
280   storage_ptr sp = {}) noexcept 280   storage_ptr sp = {}) noexcept
HITCBC 281   3 : sca_(static_cast<std::int64_t>( 281   3 : sca_(static_cast<std::int64_t>(
HITCBC 282   3 i), std::move(sp)) 282   3 i), std::move(sp))
283   { 283   {
HITCBC 284   3 } 284   3 }
285   285  
286   /// Overload 286   /// Overload
HITCBC 287   4 value( 287   4 value(
288   short i, 288   short i,
289   storage_ptr sp = {}) noexcept 289   storage_ptr sp = {}) noexcept
HITCBC 290   4 : sca_(static_cast<std::int64_t>( 290   4 : sca_(static_cast<std::int64_t>(
HITCBC 291   4 i), std::move(sp)) 291   4 i), std::move(sp))
292   { 292   {
HITCBC 293   4 } 293   4 }
294   294  
295   /// Overload 295   /// Overload
HITCBC 296   11288 value( 296   11288 value(
297   int i, 297   int i,
298   storage_ptr sp = {}) noexcept 298   storage_ptr sp = {}) noexcept
HITCBC 299   11288 : sca_(static_cast<std::int64_t>(i), 299   11288 : sca_(static_cast<std::int64_t>(i),
HITCBC 300   11288 std::move(sp)) 300   11288 std::move(sp))
301   { 301   {
HITCBC 302   11288 } 302   11288 }
303   303  
304   /// Overload 304   /// Overload
HITCBC 305   5834 value( 305   5834 value(
306   long i, 306   long i,
307   storage_ptr sp = {}) noexcept 307   storage_ptr sp = {}) noexcept
HITCBC 308   5834 : sca_(static_cast<std::int64_t>(i), 308   5834 : sca_(static_cast<std::int64_t>(i),
HITCBC 309   5834 std::move(sp)) 309   5834 std::move(sp))
310   { 310   {
HITCBC 311   5834 } 311   5834 }
312   312  
313   /// Overload 313   /// Overload
HITCBC 314   3 value( 314   3 value(
315   long long i, 315   long long i,
316   storage_ptr sp = {}) noexcept 316   storage_ptr sp = {}) noexcept
HITCBC 317   3 : sca_(static_cast<std::int64_t>(i), 317   3 : sca_(static_cast<std::int64_t>(i),
HITCBC 318   3 std::move(sp)) 318   3 std::move(sp))
319   { 319   {
HITCBC 320   3 } 320   3 }
321   321  
322   /** Overload 322   /** Overload
323   323  
324   @param u The number to construct with. 324   @param u The number to construct with.
325   @param sp 325   @param sp
326   */ 326   */
HITCBC 327   23 value( 327   23 value(
328   unsigned char u, 328   unsigned char u,
329   storage_ptr sp = {}) noexcept 329   storage_ptr sp = {}) noexcept
HITCBC 330   23 : sca_(static_cast<std::uint64_t>( 330   23 : sca_(static_cast<std::uint64_t>(
HITCBC 331   23 u), std::move(sp)) 331   23 u), std::move(sp))
332   { 332   {
HITCBC 333   23 } 333   23 }
334   334  
335   /// Overload 335   /// Overload
HITCBC 336   3 value( 336   3 value(
337   unsigned short u, 337   unsigned short u,
338   storage_ptr sp = {}) noexcept 338   storage_ptr sp = {}) noexcept
HITCBC 339   3 : sca_(static_cast<std::uint64_t>(u), 339   3 : sca_(static_cast<std::uint64_t>(u),
HITCBC 340   3 std::move(sp)) 340   3 std::move(sp))
341   { 341   {
HITCBC 342   3 } 342   3 }
343   343  
344   /// Overload 344   /// Overload
HITCBC 345   52 value( 345   52 value(
346   unsigned int u, 346   unsigned int u,
347   storage_ptr sp = {}) noexcept 347   storage_ptr sp = {}) noexcept
HITCBC 348   52 : sca_(static_cast<std::uint64_t>(u), 348   52 : sca_(static_cast<std::uint64_t>(u),
HITCBC 349   52 std::move(sp)) 349   52 std::move(sp))
350   { 350   {
HITCBC 351   52 } 351   52 }
352   352  
353   /// Overload 353   /// Overload
HITCBC 354   215 value( 354   215 value(
355   unsigned long u, 355   unsigned long u,
356   storage_ptr sp = {}) noexcept 356   storage_ptr sp = {}) noexcept
HITCBC 357   215 : sca_(static_cast<std::uint64_t>(u), 357   215 : sca_(static_cast<std::uint64_t>(u),
HITCBC 358   215 std::move(sp)) 358   215 std::move(sp))
359   { 359   {
HITCBC 360   215 } 360   215 }
361   361  
362   /// Overload 362   /// Overload
HITCBC 363   2 value( 363   2 value(
364   unsigned long long u, 364   unsigned long long u,
365   storage_ptr sp = {}) noexcept 365   storage_ptr sp = {}) noexcept
HITCBC 366   2 : sca_(static_cast<std::uint64_t>(u), 366   2 : sca_(static_cast<std::uint64_t>(u),
HITCBC 367   2 std::move(sp)) 367   2 std::move(sp))
368   { 368   {
HITCBC 369   2 } 369   2 }
370   370  
371   /** Overload 371   /** Overload
372   372  
373   @param d The number to construct with. 373   @param d The number to construct with.
374   @param sp 374   @param sp
375   */ 375   */
HITCBC 376   2039949 value( 376   2039949 value(
377   double d, 377   double d,
378   storage_ptr sp = {}) noexcept 378   storage_ptr sp = {}) noexcept
HITCBC 379   2039949 : sca_(d, std::move(sp)) 379   2039949 : sca_(d, std::move(sp))
380   { 380   {
HITCBC 381   2039949 } 381   2039949 }
382   382  
383   /** Overload 383   /** Overload
384   384  
385   @param s The string to construct with. 385   @param s The string to construct with.
386   @param sp 386   @param sp
387   */ 387   */
HITCBC 388   17178 value( 388   17178 value(
389   string_view s, 389   string_view s,
390   storage_ptr sp = {}) 390   storage_ptr sp = {})
HITCBC 391   17178 : str_(s, std::move(sp)) 391   17178 : str_(s, std::move(sp))
392   { 392   {
HITCBC 393   17170 } 393   17170 }
394   394  
395   /// Overload 395   /// Overload
HITCBC 396   136 value( 396   136 value(
397   char const* s, 397   char const* s,
398   storage_ptr sp = {}) 398   storage_ptr sp = {})
HITCBC 399   136 : str_(s, std::move(sp)) 399   136 : str_(s, std::move(sp))
400   { 400   {
HITCBC 401   136 } 401   136 }
402   402  
403   /// Overload 403   /// Overload
HITCBC 404   401 value( 404   401 value(
405   string s) noexcept 405   string s) noexcept
HITCBC 406   401 : str_(std::move(s)) 406   401 : str_(std::move(s))
407   { 407   {
HITCBC 408   401 } 408   401 }
409   409  
410   /// Overload 410   /// Overload
HITCBC 411   12 value( 411   12 value(
412   string const& s, 412   string const& s,
413   storage_ptr sp) 413   storage_ptr sp)
HITCBC 414   12 : str_( 414   12 : str_(
415   s, 415   s,
HITCBC 416   12 std::move(sp)) 416   12 std::move(sp))
417   { 417   {
HITCBC 418   12 } 418   12 }
419   419  
420   /// Overload 420   /// Overload
HITCBC 421   9 value( 421   9 value(
422   string&& s, 422   string&& s,
423   storage_ptr sp) 423   storage_ptr sp)
HITCBC 424   18 : str_( 424   18 : str_(
HITCBC 425   9 std::move(s), 425   9 std::move(s),
HITCBC 426   9 std::move(sp)) 426   9 std::move(sp))
427   { 427   {
HITCBC 428   9 } 428   9 }
429   429  
430   /// Overload 430   /// Overload
HITCBC 431   8977 value( 431   8977 value(
432   string_kind_t, 432   string_kind_t,
433   storage_ptr sp = {}) noexcept 433   storage_ptr sp = {}) noexcept
HITCBC 434   8977 : str_(std::move(sp)) 434   8977 : str_(std::move(sp))
435   { 435   {
HITCBC 436   8977 } 436   8977 }
437   437  
438   /** Overload 438   /** Overload
439   439  
440   @param arr The array to construct with. 440   @param arr The array to construct with.
441   */ 441   */
HITCBC 442   181 value(array arr) noexcept 442   181 value(array arr) noexcept
HITCBC 443   181 : arr_(std::move(arr)) 443   181 : arr_(std::move(arr))
444   { 444   {
HITCBC 445   181 } 445   181 }
446   446  
447   /// Overload 447   /// Overload
HITCBC 448   4 value( 448   4 value(
449   array const& arr, 449   array const& arr,
450   storage_ptr sp) 450   storage_ptr sp)
HITCBC 451   4 : arr_( 451   4 : arr_(
452   arr, 452   arr,
HITCBC 453   4 std::move(sp)) 453   4 std::move(sp))
454   { 454   {
HITCBC 455   4 } 455   4 }
456   456  
457   /// Overload 457   /// Overload
HITCBC 458   23 value( 458   23 value(
459   array&& arr, 459   array&& arr,
460   storage_ptr sp) 460   storage_ptr sp)
HITCBC 461   46 : arr_( 461   46 : arr_(
HITCBC 462   23 std::move(arr), 462   23 std::move(arr),
HITCBC 463   23 std::move(sp)) 463   23 std::move(sp))
464   { 464   {
HITCBC 465   23 } 465   23 }
466   466  
467   /// Overload 467   /// Overload
HITCBC 468   17 value( 468   17 value(
469   array_kind_t, 469   array_kind_t,
470   storage_ptr sp = {}) noexcept 470   storage_ptr sp = {}) noexcept
HITCBC 471   17 : arr_(std::move(sp)) 471   17 : arr_(std::move(sp))
472   { 472   {
HITCBC 473   17 } 473   17 }
474   474  
475   /** Overload 475   /** Overload
476   476  
477   @param obj The object to construct with. 477   @param obj The object to construct with.
478   */ 478   */
HITCBC 479   61 value(object obj) noexcept 479   61 value(object obj) noexcept
HITCBC 480   61 : obj_(std::move(obj)) 480   61 : obj_(std::move(obj))
481   { 481   {
HITCBC 482   61 } 482   61 }
483   483  
484   /// Overload 484   /// Overload
HITCBC 485   4 value( 485   4 value(
486   object const& obj, 486   object const& obj,
487   storage_ptr sp) 487   storage_ptr sp)
HITCBC 488   4 : obj_( obj, std::move(sp) ) 488   4 : obj_( obj, std::move(sp) )
489   { 489   {
HITCBC 490   4 } 490   4 }
491   491  
492   /// Overload 492   /// Overload
HITCBC 493   57 value( 493   57 value(
494   object&& obj, 494   object&& obj,
495   storage_ptr sp) 495   storage_ptr sp)
HITCBC 496   57 : obj_( std::move(obj), std::move(sp) ) 496   57 : obj_( std::move(obj), std::move(sp) )
497   { 497   {
HITCBC 498   57 } 498   57 }
499   499  
500   /// Overload 500   /// Overload
HITCBC 501   18 value( 501   18 value(
502   object_kind_t, 502   object_kind_t,
503   storage_ptr sp = {}) noexcept 503   storage_ptr sp = {}) noexcept
HITCBC 504   18 : obj_(std::move(sp)) 504   18 : obj_(std::move(sp))
505   { 505   {
HITCBC 506   18 } 506   18 }
507   507  
508   /** Overload 508   /** Overload
509   509  
510   @param init The initializer list to construct from. 510   @param init The initializer list to construct from.
511   @param sp 511   @param sp
512   */ 512   */
513   BOOST_JSON_DECL 513   BOOST_JSON_DECL
514   value( 514   value(
515   std::initializer_list<value_ref> init, 515   std::initializer_list<value_ref> init,
516   storage_ptr sp = {}); 516   storage_ptr sp = {});
517   517  
518   /** Overload 518   /** Overload
519   519  
520   @param other Another `value`. 520   @param other Another `value`.
521   */ 521   */
HITCBC 522   19 value(value const& other) 522   19 value(value const& other)
HITCBC 523   19 : value(other, other.storage()) 523   19 : value(other, other.storage())
524   { 524   {
HITCBC 525   19 } 525   19 }
526   526  
527   /// Overload 527   /// Overload
528   BOOST_JSON_DECL 528   BOOST_JSON_DECL
529   value( 529   value(
530   value const& other, 530   value const& other,
531   storage_ptr sp); 531   storage_ptr sp);
532   532  
533   /// Overload 533   /// Overload
534   BOOST_JSON_DECL 534   BOOST_JSON_DECL
535   value(value&& other) noexcept; 535   value(value&& other) noexcept;
536   536  
537   /// Overload 537   /// Overload
538   BOOST_JSON_DECL 538   BOOST_JSON_DECL
539   value( 539   value(
540   value&& other, 540   value&& other,
541   storage_ptr sp); 541   storage_ptr sp);
542   542  
543   /// Overload 543   /// Overload
HITCBC 544   2129161 value(pilfered<value> other) noexcept 544   2129161 value(pilfered<value> other) noexcept
HITCBC 545   2129161 { 545   2129161 {
HITCBC 546   2129161 relocate(this, other.get()); 546   2129161 relocate(this, other.get());
HITCBC 547   2129161 ::new(&other.get().sca_) scalar(); 547   2129161 ::new(&other.get().sca_) scalar();
HITCBC 548   2129161 } 548   2129161 }
549   /// @} 549   /// @}
550   550  
551   //------------------------------------------------------ 551   //------------------------------------------------------
552   // 552   //
553   // Assignment 553   // Assignment
554   // 554   //
555   //------------------------------------------------------ 555   //------------------------------------------------------
556   556  
557   /** Assignment. 557   /** Assignment.
558   558  
559   Replaces the contents of this value. 559   Replaces the contents of this value.
560   560  
561   @li **(1)** replaces with an element-wise copy of the contents of 561   @li **(1)** replaces with an element-wise copy of the contents of
562   `other`. 562   `other`.
563   @li **(2)** replaces with the contents `other` using move semantics 563   @li **(2)** replaces with the contents `other` using move semantics
564   (see below). 564   (see below).
565   @li **(3)** replaces with the value formed by constructing from `init` 565   @li **(3)** replaces with the value formed by constructing from `init`
566   and `this->storage()` (see \<\<initializer_lists\>\>). 566   and `this->storage()` (see \<\<initializer_lists\>\>).
567   @li **(4)** replaces with null. 567   @li **(4)** replaces with null.
568   @li **(5)** replaces with the boolean value `b`. 568   @li **(5)** replaces with the boolean value `b`.
569   @li **(6)**--**(10)** replaces with the signed integer `i`. 569   @li **(6)**--**(10)** replaces with the signed integer `i`.
570   @li **(11)**--**(15)** replaces with the unsigned integer `u`. 570   @li **(11)**--**(15)** replaces with the unsigned integer `u`.
571   @li **(16)** replaces with the number `d`. 571   @li **(16)** replaces with the number `d`.
572   @li **(17)**, **(19)** replaces with a copy of the string `s`. 572   @li **(17)**, **(19)** replaces with a copy of the string `s`.
573   @li **(18)**, equivalent to `*this = string_view(s)`. 573   @li **(18)**, equivalent to `*this = string_view(s)`.
574   @li **(20)** replaces with the string `s` using move semantics 574   @li **(20)** replaces with the string `s` using move semantics
575   see below. 575   see below.
576   @li **(21)** replaces with a copy of the array `arr`. 576   @li **(21)** replaces with a copy of the array `arr`.
577   @li **(22)** replaces with the array `arr` using move semantics 577   @li **(22)** replaces with the array `arr` using move semantics
578   (see below). 578   (see below).
579   @li **(23)** replaces with a copy of the object `obj`. 579   @li **(23)** replaces with a copy of the object `obj`.
580   @li **(24)** replaces with the object `obj` using move semantics 580   @li **(24)** replaces with the object `obj` using move semantics
581   (see below). 581   (see below).
582   582  
583   Move assignment for `value` never changes the associated memory 583   Move assignment for `value` never changes the associated memory
584   resource. Because of this if the memory resource of the assigned value 584   resource. Because of this if the memory resource of the assigned value
585   differs from that of `*this`, the operation is equivalent to a copy. 585   differs from that of `*this`, the operation is equivalent to a copy.
586   Otherwise, it replaces the underlying storage in constant time without 586   Otherwise, it replaces the underlying storage in constant time without
587   the possibility of exceptions. 587   the possibility of exceptions.
588   588  
589   @par Complexity 589   @par Complexity
590   @li **(1)** linear in the sizes of `*this` and `other`. 590   @li **(1)** linear in the sizes of `*this` and `other`.
591   @li **(2)** constant if `*this->storage() == *other.storage()`, 591   @li **(2)** constant if `*this->storage() == *other.storage()`,
592   otherwise linear in the sizes of `*this` and `other`. 592   otherwise linear in the sizes of `*this` and `other`.
593   @li **(3)** linear in the sizes of `*this` and `init`. 593   @li **(3)** linear in the sizes of `*this` and `init`.
594   @li **(4)**--**(16)** linear in the size of `*this`. 594   @li **(4)**--**(16)** linear in the size of `*this`.
595   @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`. 595   @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`.
596   @li **(18)** linear in the size of `*this` and `std::strlen(s)`. 596   @li **(18)** linear in the size of `*this` and `std::strlen(s)`.
597   @li **(22)** constant if `*this->storage() == *s.storage()`, 597   @li **(22)** constant if `*this->storage() == *s.storage()`,
598   otherwise linear in the size of `*this` and `s.size()`. 598   otherwise linear in the size of `*this` and `s.size()`.
599   @li **(21)** linear in the size of `*this` and `arr.size()`. 599   @li **(21)** linear in the size of `*this` and `arr.size()`.
600   @li **(22)** constant if `*this->storage() == *arr.storage()`, 600   @li **(22)** constant if `*this->storage() == *arr.storage()`,
601   otherwise linear in the size of `*this` and `arr.size()`. 601   otherwise linear in the size of `*this` and `arr.size()`.
602   @li **(23)** linear in the size of `*this` and `obj.size()`. 602   @li **(23)** linear in the size of `*this` and `obj.size()`.
603   @li **(24)** constant if `*this->storage() == *obj.storage()`, 603   @li **(24)** constant if `*this->storage() == *obj.storage()`,
604   otherwise linear in the size of `*this` and `obj.size()`. 604   otherwise linear in the size of `*this` and `obj.size()`.
605   605  
606   The size of `*this` is either the size of the underlying container 606   The size of `*this` is either the size of the underlying container
607   (if there is one), or can be considered to be 1. 607   (if there is one), or can be considered to be 1.
608   608  
609   @par Exception Safety 609   @par Exception Safety
610   @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee. 610   @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee.
611   @li **(4)**--**(16)** no-throw guarantee. 611   @li **(4)**--**(16)** no-throw guarantee.
612   612  
613   Calls to `memory_resource::allocate` may throw. 613   Calls to `memory_resource::allocate` may throw.
614   614  
615   @param other The source value. 615   @param other The source value.
616   616  
617   @{ 617   @{
618   */ 618   */
619   BOOST_JSON_DECL 619   BOOST_JSON_DECL
620   value& 620   value&
621   operator=(value const& other); 621   operator=(value const& other);
622   622  
623   /** Overload 623   /** Overload
624   624  
625   The contents of the value are replaced with the 625   The contents of the value are replaced with the
626   contents of `other` using move semantics: 626   contents of `other` using move semantics:
627   627  
628   @li If `*other.storage() == *sp`, ownership of 628   @li If `*other.storage() == *sp`, ownership of
629   the underlying memory is transferred in constant 629   the underlying memory is transferred in constant
630   time, with no possibility of exceptions. 630   time, with no possibility of exceptions.
631   After assignment, the moved-from value becomes 631   After assignment, the moved-from value becomes
632   a null with its current storage pointer. 632   a null with its current storage pointer.
633   633  
634   @li If `*other.storage() != *sp`, an 634   @li If `*other.storage() != *sp`, an
635   element-wise copy is performed if 635   element-wise copy is performed if
636   `other.is_structured() == true`, which may throw. 636   `other.is_structured() == true`, which may throw.
637   In this case, the moved-from value is not 637   In this case, the moved-from value is not
638   changed. 638   changed.
639   */ 639   */
640   BOOST_JSON_DECL 640   BOOST_JSON_DECL
641   value& 641   value&
642   operator=(value&& other); 642   operator=(value&& other);
643   643  
644   /** Overload 644   /** Overload
645   645  
646   @param init The initializer list to assign from. 646   @param init The initializer list to assign from.
647   */ 647   */
648   BOOST_JSON_DECL 648   BOOST_JSON_DECL
649   value& 649   value&
650   operator=( 650   operator=(
651   std::initializer_list<value_ref> init); 651   std::initializer_list<value_ref> init);
652   652  
653   /// Overload 653   /// Overload
654   value& 654   value&
HITCBC 655   18 operator=(std::nullptr_t) noexcept 655   18 operator=(std::nullptr_t) noexcept
656   { 656   {
HITCBC 657   18 if(is_scalar()) 657   18 if(is_scalar())
658   { 658   {
HITCBC 659   12 sca_.k = json::kind::null; 659   12 sca_.k = json::kind::null;
660   } 660   }
661   else 661   else
662   { 662   {
HITCBC 663   18 ::new(&sca_) scalar( 663   18 ::new(&sca_) scalar(
HITCBC 664   6 destroy()); 664   6 destroy());
665   } 665   }
HITCBC 666   18 return *this; 666   18 return *this;
667   } 667   }
668   668  
669   /** Overload 669   /** Overload
670   670  
671   @param b The new value. 671   @param b The new value.
672   */ 672   */
673   #ifdef BOOST_JSON_DOCS 673   #ifdef BOOST_JSON_DOCS
674   value& operator=(bool b) noexcept; 674   value& operator=(bool b) noexcept;
675   #else 675   #else
676   template<class T 676   template<class T
677   ,class = typename std::enable_if< 677   ,class = typename std::enable_if<
678   std::is_same<T, bool>::value>::type 678   std::is_same<T, bool>::value>::type
679   > 679   >
HITCBC 680   51 value& operator=(T b) noexcept 680   51 value& operator=(T b) noexcept
681   { 681   {
HITCBC 682   51 if(is_scalar()) 682   51 if(is_scalar())
683   { 683   {
HITCBC 684   50 sca_.b = b; 684   50 sca_.b = b;
HITCBC 685   50 sca_.k = json::kind::bool_; 685   50 sca_.k = json::kind::bool_;
686   } 686   }
687   else 687   else
688   { 688   {
HITCBC 689   1 ::new(&sca_) scalar( 689   1 ::new(&sca_) scalar(
690   b, destroy()); 690   b, destroy());
691   } 691   }
HITCBC 692   51 return *this; 692   51 return *this;
693   } 693   }
694   #endif 694   #endif
695   695  
696   /** Overload 696   /** Overload
697   697  
698   @param i The new value. 698   @param i The new value.
699   */ 699   */
HITCBC 700   2 value& operator=(signed char i) noexcept 700   2 value& operator=(signed char i) noexcept
701   { 701   {
HITCBC 702   2 return operator=( 702   2 return operator=(
HITCBC 703   2 static_cast<long long>(i)); 703   2 static_cast<long long>(i));
704   } 704   }
705   705  
706   /// Overload 706   /// Overload
HITCBC 707   8 value& operator=(short i) noexcept 707   8 value& operator=(short i) noexcept
708   { 708   {
HITCBC 709   8 return operator=( 709   8 return operator=(
HITCBC 710   8 static_cast<long long>(i)); 710   8 static_cast<long long>(i));
711   } 711   }
712   712  
713   /// Overload 713   /// Overload
HITCBC 714   6529 value& operator=(int i) noexcept 714   6529 value& operator=(int i) noexcept
715   { 715   {
HITCBC 716   6529 return operator=( 716   6529 return operator=(
HITCBC 717   6529 static_cast<long long>(i)); 717   6529 static_cast<long long>(i));
718   } 718   }
719   719  
720   /// Overload 720   /// Overload
HITCBC 721   12 value& operator=(long i) noexcept 721   12 value& operator=(long i) noexcept
722   { 722   {
HITCBC 723   12 return operator=( 723   12 return operator=(
HITCBC 724   12 static_cast<long long>(i)); 724   12 static_cast<long long>(i));
725   } 725   }
726   726  
727   /// Overload 727   /// Overload
HITCBC 728   6559 value& operator=(long long i) noexcept 728   6559 value& operator=(long long i) noexcept
729   { 729   {
HITCBC 730   6559 if(is_scalar()) 730   6559 if(is_scalar())
731   { 731   {
HITCBC 732   6556 sca_.i = i; 732   6556 sca_.i = i;
HITCBC 733   6556 sca_.k = json::kind::int64; 733   6556 sca_.k = json::kind::int64;
734   } 734   }
735   else 735   else
736   { 736   {
HITCBC 737   9 ::new(&sca_) scalar(static_cast< 737   9 ::new(&sca_) scalar(static_cast<
HITCBC 738   3 std::int64_t>(i), destroy()); 738   3 std::int64_t>(i), destroy());
739   } 739   }
HITCBC 740   6559 return *this; 740   6559 return *this;
741   } 741   }
742   742  
743   /** Overload 743   /** Overload
744   744  
745   @param u The new value. 745   @param u The new value.
746   */ 746   */
HITCBC 747   6 value& operator=(unsigned char u) noexcept 747   6 value& operator=(unsigned char u) noexcept
748   { 748   {
HITCBC 749   6 return operator=(static_cast< 749   6 return operator=(static_cast<
HITCBC 750   6 unsigned long long>(u)); 750   6 unsigned long long>(u));
751   } 751   }
752   752  
753   /// Overload 753   /// Overload
HITCBC 754   8 value& operator=(unsigned short u) noexcept 754   8 value& operator=(unsigned short u) noexcept
755   { 755   {
HITCBC 756   8 return operator=(static_cast< 756   8 return operator=(static_cast<
HITCBC 757   8 unsigned long long>(u)); 757   8 unsigned long long>(u));
758   } 758   }
759   759  
760   /// Overload 760   /// Overload
HITCBC 761   8 value& operator=(unsigned int u) noexcept 761   8 value& operator=(unsigned int u) noexcept
762   { 762   {
HITCBC 763   8 return operator=(static_cast< 763   8 return operator=(static_cast<
HITCBC 764   8 unsigned long long>(u)); 764   8 unsigned long long>(u));
765   } 765   }
766   766  
767   /// Overload 767   /// Overload
HITCBC 768   17 value& operator=(unsigned long u) noexcept 768   17 value& operator=(unsigned long u) noexcept
769   { 769   {
HITCBC 770   17 return operator=(static_cast< 770   17 return operator=(static_cast<
HITCBC 771   17 unsigned long long>(u)); 771   17 unsigned long long>(u));
772   } 772   }
773   773  
774   /// Overload 774   /// Overload
HITCBC 775   47 value& operator=(unsigned long long u) noexcept 775   47 value& operator=(unsigned long long u) noexcept
776   { 776   {
HITCBC 777   47 if(is_scalar()) 777   47 if(is_scalar())
778   { 778   {
HITCBC 779   46 sca_.u = u; 779   46 sca_.u = u;
HITCBC 780   46 sca_.k = json::kind::uint64; 780   46 sca_.k = json::kind::uint64;
781   } 781   }
782   else 782   else
783   { 783   {
HITCBC 784   3 ::new(&sca_) scalar(static_cast< 784   3 ::new(&sca_) scalar(static_cast<
HITCBC 785   1 std::uint64_t>(u), destroy()); 785   1 std::uint64_t>(u), destroy());
786   } 786   }
HITCBC 787   47 return *this; 787   47 return *this;
788   } 788   }
789   789  
790   /** Overload 790   /** Overload
791   791  
792   @param d The new value. 792   @param d The new value.
793   */ 793   */
HITCBC 794   32 value& operator=(double d) noexcept 794   32 value& operator=(double d) noexcept
795   { 795   {
HITCBC 796   32 if(is_scalar()) 796   32 if(is_scalar())
797   { 797   {
HITCBC 798   25 sca_.d = d; 798   25 sca_.d = d;
HITCBC 799   25 sca_.k = json::kind::double_; 799   25 sca_.k = json::kind::double_;
800   } 800   }
801   else 801   else
802   { 802   {
HITCBC 803   21 ::new(&sca_) scalar( 803   21 ::new(&sca_) scalar(
HITCBC 804   7 d, destroy()); 804   7 d, destroy());
805   } 805   }
HITCBC 806   32 return *this; 806   32 return *this;
807   } 807   }
808   808  
809   /** Overload 809   /** Overload
810   810  
811   @param s The new string. 811   @param s The new string.
812   */ 812   */
813   BOOST_JSON_DECL 813   BOOST_JSON_DECL
814   value& operator=(string_view s); 814   value& operator=(string_view s);
815   815  
816   /// Overload 816   /// Overload
817   BOOST_JSON_DECL 817   BOOST_JSON_DECL
818   value& operator=(char const* s); 818   value& operator=(char const* s);
819   819  
820   /// Overload 820   /// Overload
821   BOOST_JSON_DECL 821   BOOST_JSON_DECL
822   value& operator=(string const& s); 822   value& operator=(string const& s);
823   823  
824   /** Overload 824   /** Overload
825   825  
826   The contents of the value are replaced with the 826   The contents of the value are replaced with the
827   contents of `s` using move semantics: 827   contents of `s` using move semantics:
828   828  
829   @li If `*other.storage() == *this->storage()`, 829   @li If `*other.storage() == *this->storage()`,
830   ownership of the underlying memory is transferred 830   ownership of the underlying memory is transferred
831   in constant time, with no possibility of exceptions. 831   in constant time, with no possibility of exceptions.
832   After assignment, the moved-from string becomes 832   After assignment, the moved-from string becomes
833   empty with its current storage pointer. 833   empty with its current storage pointer.
834   834  
835   @li If `*other.storage() != *this->storage()`, an 835   @li If `*other.storage() != *this->storage()`, an
836   element-wise copy is performed, which may throw. 836   element-wise copy is performed, which may throw.
837   In this case, the moved-from string is not 837   In this case, the moved-from string is not
838   changed. 838   changed.
839   839  
840   @param s The string to move-assign from. 840   @param s The string to move-assign from.
841   */ 841   */
842   BOOST_JSON_DECL 842   BOOST_JSON_DECL
843   value& operator=(string&& s); 843   value& operator=(string&& s);
844   844  
845   /** Overload 845   /** Overload
846   846  
847   Replace `*this` with a copy of the array `arr`. 847   Replace `*this` with a copy of the array `arr`.
848   848  
849   @par Exception Safety 849   @par Exception Safety
850   Strong guarantee. 850   Strong guarantee.
851   Calls to `memory_resource::allocate` may throw. 851   Calls to `memory_resource::allocate` may throw.
852   852  
853   @par Complexity 853   @par Complexity
854   Linear in the sum of sizes of `*this` and `arr` 854   Linear in the sum of sizes of `*this` and `arr`
855   855  
856   @param arr The new array. 856   @param arr The new array.
857   */ 857   */
858   BOOST_JSON_DECL 858   BOOST_JSON_DECL
859   value& operator=(array const& arr); 859   value& operator=(array const& arr);
860   860  
861   /** Overload 861   /** Overload
862   862  
863   The contents of the value are replaced with the 863   The contents of the value are replaced with the
864   contents of `arr` using move semantics: 864   contents of `arr` using move semantics:
865   865  
866   @li If `*arr.storage() == *this->storage()`, 866   @li If `*arr.storage() == *this->storage()`,
867   ownership of the underlying memory is transferred 867   ownership of the underlying memory is transferred
868   in constant time, with no possibility of exceptions. 868   in constant time, with no possibility of exceptions.
869   After assignment, the moved-from array becomes 869   After assignment, the moved-from array becomes
870   empty with its current storage pointer. 870   empty with its current storage pointer.
871   871  
872   @li If `*arr.storage() != *this->storage()`, an 872   @li If `*arr.storage() != *this->storage()`, an
873   element-wise copy is performed, which may throw. 873   element-wise copy is performed, which may throw.
874   In this case, the moved-from array is not 874   In this case, the moved-from array is not
875   changed. 875   changed.
876   876  
877   @par Complexity 877   @par Complexity
878   Constant, or linear in the size of `*this` plus `arr.size()`. 878   Constant, or linear in the size of `*this` plus `arr.size()`.
879   879  
880   @par Exception Safety 880   @par Exception Safety
881   Strong guarantee. 881   Strong guarantee.
882   Calls to `memory_resource::allocate` may throw. 882   Calls to `memory_resource::allocate` may throw.
883   883  
884   @param arr The array to move-assign from. 884   @param arr The array to move-assign from.
885   */ 885   */
886   BOOST_JSON_DECL 886   BOOST_JSON_DECL
887   value& operator=(array&& arr); 887   value& operator=(array&& arr);
888   888  
889   /** Overload 889   /** Overload
890   890  
891   Replace `*this` with a copy of the obect `obj`. 891   Replace `*this` with a copy of the obect `obj`.
892   892  
893   @par Exception Safety 893   @par Exception Safety
894   Strong guarantee. 894   Strong guarantee.
895   Calls to `memory_resource::allocate` may throw. 895   Calls to `memory_resource::allocate` may throw.
896   896  
897   @par Complexity 897   @par Complexity
898   Linear in the sum of sizes of `*this` and `obj` 898   Linear in the sum of sizes of `*this` and `obj`
899   899  
900   @param obj The new object. 900   @param obj The new object.
901   */ 901   */
902   BOOST_JSON_DECL 902   BOOST_JSON_DECL
903   value& operator=(object const& obj); 903   value& operator=(object const& obj);
904   904  
905   /** Overload 905   /** Overload
906   906  
907   The contents of the value are replaced with the 907   The contents of the value are replaced with the
908   contents of `obj` using move semantics: 908   contents of `obj` using move semantics:
909   909  
910   @li If `*obj.storage() == *this->storage()`, 910   @li If `*obj.storage() == *this->storage()`,
911   ownership of the underlying memory is transferred 911   ownership of the underlying memory is transferred
912   in constant time, with no possibility of exceptions. 912   in constant time, with no possibility of exceptions.
913   After assignment, the moved-from object becomes 913   After assignment, the moved-from object becomes
914   empty with its current storage pointer. 914   empty with its current storage pointer.
915   915  
916   @li If `*obj.storage() != *this->storage()`, an 916   @li If `*obj.storage() != *this->storage()`, an
917   element-wise copy is performed, which may throw. 917   element-wise copy is performed, which may throw.
918   In this case, the moved-from object is not 918   In this case, the moved-from object is not
919   changed. 919   changed.
920   920  
921   @par Complexity 921   @par Complexity
922   Constant, or linear in the size of `*this` plus `obj.size()`. 922   Constant, or linear in the size of `*this` plus `obj.size()`.
923   923  
924   @par Exception Safety 924   @par Exception Safety
925   Strong guarantee. 925   Strong guarantee.
926   Calls to `memory_resource::allocate` may throw. 926   Calls to `memory_resource::allocate` may throw.
927   927  
928   @param obj The object to move-assign from. 928   @param obj The object to move-assign from.
929   */ 929   */
930   BOOST_JSON_DECL 930   BOOST_JSON_DECL
931   value& operator=(object&& obj); 931   value& operator=(object&& obj);
932   /// @} 932   /// @}
933   933  
934   //------------------------------------------------------ 934   //------------------------------------------------------
935   // 935   //
936   // Modifiers 936   // Modifiers
937   // 937   //
938   //------------------------------------------------------ 938   //------------------------------------------------------
939   939  
940   /** Replace with a null value. 940   /** Replace with a null value.
941   941  
942   The current value is destroyed and the kind is changed to kind::null. 942   The current value is destroyed and the kind is changed to kind::null.
943   The associated memeory resource is kept unchanged. 943   The associated memeory resource is kept unchanged.
944   944  
945   @par Complexity 945   @par Complexity
946   Linear in the size of `*this`. 946   Linear in the size of `*this`.
947   947  
948   @par Exception Safety 948   @par Exception Safety
949   No-throw guarantee. 949   No-throw guarantee.
950   */ 950   */
951   void 951   void
HITCBC 952   8 emplace_null() noexcept 952   8 emplace_null() noexcept
953   { 953   {
HITCBC 954   8 *this = nullptr; 954   8 *this = nullptr;
HITCBC 955   8 } 955   8 }
956   956  
957   /** Replace with a `bool` value. 957   /** Replace with a `bool` value.
958   958  
959   The value is replaced with a `bool` initialized to `false`, destroying 959   The value is replaced with a `bool` initialized to `false`, destroying
960   the previous contents, but keeping the memeory resource. 960   the previous contents, but keeping the memeory resource.
961   961  
962   @par Complexity 962   @par Complexity
963   Linear in the size of `*this`. 963   Linear in the size of `*this`.
964   964  
965   @par Exception Safety 965   @par Exception Safety
966   No-throw guarantee. 966   No-throw guarantee.
967   967  
968   @return `this->get_bool()`. 968   @return `this->get_bool()`.
969   */ 969   */
970   bool& 970   bool&
HITCBC 971   1 emplace_bool() noexcept 971   1 emplace_bool() noexcept
972   { 972   {
HITCBC 973   1 *this = false; 973   1 *this = false;
HITCBC 974   1 return sca_.b; 974   1 return sca_.b;
975   } 975   }
976   976  
977   /** Replace with a `std::int64_t` value. 977   /** Replace with a `std::int64_t` value.
978   978  
979   The value is replaced with a `std::int64_t` initialized to zero, 979   The value is replaced with a `std::int64_t` initialized to zero,
980   destroying the previous contents, but keeping the memeory resource. 980   destroying the previous contents, but keeping the memeory resource.
981   981  
982   @par Complexity 982   @par Complexity
983   Linear in the size of `*this`. 983   Linear in the size of `*this`.
984   984  
985   @par Exception Safety 985   @par Exception Safety
986   No-throw guarantee. 986   No-throw guarantee.
987   987  
988   @return `this->get_int64()`. 988   @return `this->get_int64()`.
989   */ 989   */
990   std::int64_t& 990   std::int64_t&
HITCBC 991   2 emplace_int64() noexcept 991   2 emplace_int64() noexcept
992   { 992   {
HITCBC 993   2 *this = std::int64_t{}; 993   2 *this = std::int64_t{};
HITCBC 994   2 return sca_.i; 994   2 return sca_.i;
995   } 995   }
996   996  
997   /** Replace with a `std::uint64_t` value. 997   /** Replace with a `std::uint64_t` value.
998   998  
999   The value is replaced with a `std::uint64_t` initialized to zero, 999   The value is replaced with a `std::uint64_t` initialized to zero,
1000   destroying the the previous contents, but keeping the memeory resource. 1000   destroying the the previous contents, but keeping the memeory resource.
1001   1001  
1002   @par Complexity 1002   @par Complexity
1003   Linear in the size of `*this`. 1003   Linear in the size of `*this`.
1004   1004  
1005   @par Exception Safety 1005   @par Exception Safety
1006   No-throw guarantee. 1006   No-throw guarantee.
1007   1007  
1008   @return `this->get_uint64()`. 1008   @return `this->get_uint64()`.
1009   */ 1009   */
1010   std::uint64_t& 1010   std::uint64_t&
HITCBC 1011   1 emplace_uint64() noexcept 1011   1 emplace_uint64() noexcept
1012   { 1012   {
HITCBC 1013   1 *this = std::uint64_t{}; 1013   1 *this = std::uint64_t{};
HITCBC 1014   1 return sca_.u; 1014   1 return sca_.u;
1015   } 1015   }
1016   1016  
1017   /** Replace with a `double` value. 1017   /** Replace with a `double` value.
1018   1018  
1019   The value is replaced with a `double` initialized to zero, destroying 1019   The value is replaced with a `double` initialized to zero, destroying
1020   the previous contents, but keeping the memeory resource. 1020   the previous contents, but keeping the memeory resource.
1021   1021  
1022   @par Complexity 1022   @par Complexity
1023   Linear in the size of `*this`. 1023   Linear in the size of `*this`.
1024   1024  
1025   @par Exception Safety 1025   @par Exception Safety
1026   No-throw guarantee. 1026   No-throw guarantee.
1027   1027  
1028   @return `this->get_double()`. 1028   @return `this->get_double()`.
1029   */ 1029   */
1030   double& 1030   double&
HITCBC 1031   1 emplace_double() noexcept 1031   1 emplace_double() noexcept
1032   { 1032   {
HITCBC 1033   1 *this = double{}; 1033   1 *this = double{};
HITCBC 1034   1 return sca_.d; 1034   1 return sca_.d;
1035   } 1035   }
1036   1036  
1037   /** Replace with an empty @ref string. 1037   /** Replace with an empty @ref string.
1038   1038  
1039   The value is replaced with an empty @ref string using the current 1039   The value is replaced with an empty @ref string using the current
1040   memory resource, destroying the previous contents. All previously 1040   memory resource, destroying the previous contents. All previously
1041   obtained iterators and references obtained beforehand are invalidated. 1041   obtained iterators and references obtained beforehand are invalidated.
1042   1042  
1043   @par Complexity 1043   @par Complexity
1044   Linear in the size of `*this`. 1044   Linear in the size of `*this`.
1045   1045  
1046   @par Exception Safety 1046   @par Exception Safety
1047   No-throw guarantee. 1047   No-throw guarantee.
1048   1048  
1049   @return `this->get_string()`. 1049   @return `this->get_string()`.
1050   */ 1050   */
1051   BOOST_JSON_DECL 1051   BOOST_JSON_DECL
1052   string& 1052   string&
1053   emplace_string() noexcept; 1053   emplace_string() noexcept;
1054   1054  
1055   /** Replace with an empty array. 1055   /** Replace with an empty array.
1056   1056  
1057   The value is replaced with an empty @ref array using the current memory 1057   The value is replaced with an empty @ref array using the current memory
1058   resource, destroying the previous contents. All previously obtained 1058   resource, destroying the previous contents. All previously obtained
1059   iterators and references obtained beforehand are invalidated. 1059   iterators and references obtained beforehand are invalidated.
1060   1060  
1061   @par Complexity 1061   @par Complexity
1062   Linear in the size of `*this`. 1062   Linear in the size of `*this`.
1063   1063  
1064   @par Exception Safety 1064   @par Exception Safety
1065   No-throw guarantee. 1065   No-throw guarantee.
1066   1066  
1067   @return `this->get_array()`. 1067   @return `this->get_array()`.
1068   */ 1068   */
1069   BOOST_JSON_DECL 1069   BOOST_JSON_DECL
1070   array& 1070   array&
1071   emplace_array() noexcept; 1071   emplace_array() noexcept;
1072   1072  
1073   /** Replace with an empty @ref object. 1073   /** Replace with an empty @ref object.
1074   1074  
1075   The value is replaced with an empty @ref array using the current memory 1075   The value is replaced with an empty @ref array using the current memory
1076   resource, destroying the previous contents. All previously obtained 1076   resource, destroying the previous contents. All previously obtained
1077   iterators and references obtained beforehand are invalidated. 1077   iterators and references obtained beforehand are invalidated.
1078   1078  
1079   @par Complexity 1079   @par Complexity
1080   Linear in the size of `*this`. 1080   Linear in the size of `*this`.
1081   1081  
1082   @par Exception Safety 1082   @par Exception Safety
1083   No-throw guarantee. 1083   No-throw guarantee.
1084   1084  
1085   @return `this->get_object()`. 1085   @return `this->get_object()`.
1086   */ 1086   */
1087   BOOST_JSON_DECL 1087   BOOST_JSON_DECL
1088   object& 1088   object&
1089   emplace_object() noexcept; 1089   emplace_object() noexcept;
1090   1090  
1091   /** Swap the given values. 1091   /** Swap the given values.
1092   1092  
1093   Exchanges the contents of this value with another value. Ownership of 1093   Exchanges the contents of this value with another value. Ownership of
1094   the respective @ref boost::container::pmr::memory_resource objects is 1094   the respective @ref boost::container::pmr::memory_resource objects is
1095   not transferred: 1095   not transferred:
1096   1096  
1097   @li If `this == &other`, this function has no effect. 1097   @li If `this == &other`, this function has no effect.
1098   @li If `*other.storage() == *this->storage()`, ownership of the 1098   @li If `*other.storage() == *this->storage()`, ownership of the
1099   underlying memory is swapped in constant time, with no possibility 1099   underlying memory is swapped in constant time, with no possibility
1100   of exceptions. All iterators and references remain valid. 1100   of exceptions. All iterators and references remain valid.
1101   @li If `*other.storage() != *this->storage()`, the contents are 1101   @li If `*other.storage() != *this->storage()`, the contents are
1102   logically swapped by making copies, which can throw. In this case 1102   logically swapped by making copies, which can throw. In this case
1103   all iterators and references are invalidated. 1103   all iterators and references are invalidated.
1104   1104  
1105   @par Complexity 1105   @par Complexity
1106   Constant or linear in the sum of the sizes of the values. 1106   Constant or linear in the sum of the sizes of the values.
1107   1107  
1108   @par Exception Safety 1108   @par Exception Safety
1109   Strong guarantee. Calls to `memory_resource::allocate` may throw. 1109   Strong guarantee. Calls to `memory_resource::allocate` may throw.
1110   1110  
1111   @param other The value to swap with. 1111   @param other The value to swap with.
1112   */ 1112   */
1113   BOOST_JSON_DECL 1113   BOOST_JSON_DECL
1114   void 1114   void
1115   swap(value& other); 1115   swap(value& other);
1116   1116  
1117   /** Swap the given values. 1117   /** Swap the given values.
1118   1118  
1119   Exchanges the contents of value `lhs` with another value `rhs`. 1119   Exchanges the contents of value `lhs` with another value `rhs`.
1120   Ownership of the respective @ref boost::container::pmr::memory_resource 1120   Ownership of the respective @ref boost::container::pmr::memory_resource
1121   objects is not transferred. 1121   objects is not transferred.
1122   1122  
1123   @li If `&lhs == &rhs`, this function call has no effect. 1123   @li If `&lhs == &rhs`, this function call has no effect.
1124   @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying 1124   @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1125   memory is swapped in constant time, with no possibility of 1125   memory is swapped in constant time, with no possibility of
1126   exceptions. All iterators and references remain valid. 1126   exceptions. All iterators and references remain valid.
1127   @li If `*lhs.storage() != *rhs.storage`, the contents are logically 1127   @li If `*lhs.storage() != *rhs.storage`, the contents are logically
1128   swapped by a copy, which can throw. In this case all iterators and 1128   swapped by a copy, which can throw. In this case all iterators and
1129   references are invalidated. 1129   references are invalidated.
1130   1130  
1131   @par Complexity 1131   @par Complexity
1132   Constant or linear in the sum of the sizes of the values. 1132   Constant or linear in the sum of the sizes of the values.
1133   1133  
1134   @par Exception Safety 1134   @par Exception Safety
1135   Strong guarantee. Calls to `memory_resource::allocate` may throw. 1135   Strong guarantee. Calls to `memory_resource::allocate` may throw.
1136   1136  
1137   @param lhs The value to exchange. 1137   @param lhs The value to exchange.
1138   @param rhs The value to exchange. 1138   @param rhs The value to exchange.
1139   1139  
1140   @see @ref value::swap 1140   @see @ref value::swap
1141   */ 1141   */
1142   friend 1142   friend
1143   void 1143   void
HITCBC 1144   3 swap(value& lhs, value& rhs) 1144   3 swap(value& lhs, value& rhs)
1145   { 1145   {
HITCBC 1146   3 lhs.swap(rhs); 1146   3 lhs.swap(rhs);
HITCBC 1147   3 } 1147   3 }
1148   1148  
1149   //------------------------------------------------------ 1149   //------------------------------------------------------
1150   // 1150   //
1151   // Observers 1151   // Observers
1152   // 1152   //
1153   //------------------------------------------------------ 1153   //------------------------------------------------------
1154   1154  
1155   /** Returns the kind of this JSON value. 1155   /** Returns the kind of this JSON value.
1156   1156  
1157   This function returns the discriminating enumeration constant of type 1157   This function returns the discriminating enumeration constant of type
1158   @ref json::kind corresponding to the underlying representation stored 1158   @ref json::kind corresponding to the underlying representation stored
1159   in the container. 1159   in the container.
1160   1160  
1161   @par Complexity 1161   @par Complexity
1162   Constant. 1162   Constant.
1163   1163  
1164   @par Exception Safety 1164   @par Exception Safety
1165   No-throw guarantee. 1165   No-throw guarantee.
1166   */ 1166   */
1167   json::kind 1167   json::kind
HITCBC 1168   4609688 kind() const noexcept 1168   4609688 kind() const noexcept
1169   { 1169   {
1170   return static_cast<json::kind>( 1170   return static_cast<json::kind>(
1171   static_cast<unsigned char>( 1171   static_cast<unsigned char>(
HITCBC 1172   4609688 sca_.k) & 0x3f); 1172   4609688 sca_.k) & 0x3f);
1173   } 1173   }
1174   1174  
1175   /** Check if this is an @ref array. 1175   /** Check if this is an @ref array.
1176   1176  
1177   Returns `true` if the value's @ref kind() is `kind::array`. 1177   Returns `true` if the value's @ref kind() is `kind::array`.
1178   1178  
1179   @returns `this->kind() == kind::array`. 1179   @returns `this->kind() == kind::array`.
1180   1180  
1181   @par Complexity 1181   @par Complexity
1182   Constant. 1182   Constant.
1183   1183  
1184   @par Exception Safety 1184   @par Exception Safety
1185   No-throw guarantee. 1185   No-throw guarantee.
1186   */ 1186   */
1187   bool 1187   bool
HITCBC 1188   6021 is_array() const noexcept 1188   6021 is_array() const noexcept
1189   { 1189   {
HITCBC 1190   6021 return kind() == json::kind::array; 1190   6021 return kind() == json::kind::array;
1191   } 1191   }
1192   1192  
1193   /** Check if this is an @ref object. 1193   /** Check if this is an @ref object.
1194   1194  
1195   Returns `true` if the value's @ref kind() is `kind::object`. 1195   Returns `true` if the value's @ref kind() is `kind::object`.
1196   1196  
1197   @returns `this->kind() == kind::object`. 1197   @returns `this->kind() == kind::object`.
1198   1198  
1199   @par Complexity 1199   @par Complexity
1200   Constant. 1200   Constant.
1201   1201  
1202   @par Exception Safety 1202   @par Exception Safety
1203   No-throw guarantee. 1203   No-throw guarantee.
1204   */ 1204   */
1205   bool 1205   bool
HITCBC 1206   53270 is_object() const noexcept 1206   53270 is_object() const noexcept
1207   { 1207   {
HITCBC 1208   53270 return kind() == json::kind::object; 1208   53270 return kind() == json::kind::object;
1209   } 1209   }
1210   1210  
1211   /** Check if this is a @ref string. 1211   /** Check if this is a @ref string.
1212   1212  
1213   Returns `true` if the value's @ref kind() is `kind::string`. 1213   Returns `true` if the value's @ref kind() is `kind::string`.
1214   1214  
1215   @returns `this->kind() == kind::string`. 1215   @returns `this->kind() == kind::string`.
1216   1216  
1217   @par Complexity 1217   @par Complexity
1218   Constant. 1218   Constant.
1219   1219  
1220   @par Exception Safety 1220   @par Exception Safety
1221   No-throw guarantee. 1221   No-throw guarantee.
1222   */ 1222   */
1223   bool 1223   bool
HITCBC 1224   88287 is_string() const noexcept 1224   88287 is_string() const noexcept
1225   { 1225   {
HITCBC 1226   88287 return kind() == json::kind::string; 1226   88287 return kind() == json::kind::string;
1227   } 1227   }
1228   1228  
1229   /** Check if this is a `std::int64_t`. 1229   /** Check if this is a `std::int64_t`.
1230   1230  
1231   Returns `true` if the value's @ref kind() is `kind::int64`. 1231   Returns `true` if the value's @ref kind() is `kind::int64`.
1232   1232  
1233   @returns `this->kind() == kind::int64`. 1233   @returns `this->kind() == kind::int64`.
1234   1234  
1235   @par Complexity 1235   @par Complexity
1236   Constant. 1236   Constant.
1237   1237  
1238   @par Exception Safety 1238   @par Exception Safety
1239   No-throw guarantee. 1239   No-throw guarantee.
1240   */ 1240   */
1241   bool 1241   bool
HITCBC 1242   14814 is_int64() const noexcept 1242   14814 is_int64() const noexcept
1243   { 1243   {
HITCBC 1244   14814 return kind() == json::kind::int64; 1244   14814 return kind() == json::kind::int64;
1245   } 1245   }
1246   1246  
1247   /** Checks if this is a `std::uint64_t`. 1247   /** Checks if this is a `std::uint64_t`.
1248   1248  
1249   Returns `true` if the value's @ref kind() is `kind::uint64`. 1249   Returns `true` if the value's @ref kind() is `kind::uint64`.
1250   1250  
1251   @returns `this->kind() == kind::uint64`. 1251   @returns `this->kind() == kind::uint64`.
1252   1252  
1253   @par Complexity 1253   @par Complexity
1254   Constant. 1254   Constant.
1255   1255  
1256   @par Exception Safety 1256   @par Exception Safety
1257   No-throw guarantee. 1257   No-throw guarantee.
1258   */ 1258   */
1259   bool 1259   bool
HITCBC 1260   322 is_uint64() const noexcept 1260   322 is_uint64() const noexcept
1261   { 1261   {
HITCBC 1262   322 return kind() == json::kind::uint64; 1262   322 return kind() == json::kind::uint64;
1263   } 1263   }
1264   1264  
1265   /** Check if this is a `double`. 1265   /** Check if this is a `double`.
1266   1266  
1267   Returns `true` if the value's @ref kind() is `kind::double_`. 1267   Returns `true` if the value's @ref kind() is `kind::double_`.
1268   1268  
1269   @returns `this->kind() == kind::double_`. 1269   @returns `this->kind() == kind::double_`.
1270   1270  
1271   @par Complexity 1271   @par Complexity
1272   Constant. 1272   Constant.
1273   1273  
1274   @par Exception Safety 1274   @par Exception Safety
1275   No-throw guarantee. 1275   No-throw guarantee.
1276   */ 1276   */
1277   bool 1277   bool
HITCBC 1278   2078671 is_double() const noexcept 1278   2078671 is_double() const noexcept
1279   { 1279   {
HITCBC 1280   2078671 return kind() == json::kind::double_; 1280   2078671 return kind() == json::kind::double_;
1281   } 1281   }
1282   1282  
1283   /** Check if this is a `bool`. 1283   /** Check if this is a `bool`.
1284   1284  
1285   Returns `true` if the value's @ref kind() is `kind::bool_`. 1285   Returns `true` if the value's @ref kind() is `kind::bool_`.
1286   1286  
1287   @returns `this->kind() == kind::bool_`. 1287   @returns `this->kind() == kind::bool_`.
1288   1288  
1289   @par Complexity 1289   @par Complexity
1290   Constant. 1290   Constant.
1291   1291  
1292   @par Exception Safety 1292   @par Exception Safety
1293   No-throw guarantee. 1293   No-throw guarantee.
1294   */ 1294   */
1295   bool 1295   bool
HITCBC 1296   924 is_bool() const noexcept 1296   924 is_bool() const noexcept
1297   { 1297   {
HITCBC 1298   924 return kind() == json::kind::bool_; 1298   924 return kind() == json::kind::bool_;
1299   } 1299   }
1300   1300  
1301   /** Check if this is a null value. 1301   /** Check if this is a null value.
1302   1302  
1303   Returns `true` if the value's @ref kind() is `kind::null`. 1303   Returns `true` if the value's @ref kind() is `kind::null`.
1304   1304  
1305   @returns `this->kind() == kind::null`. 1305   @returns `this->kind() == kind::null`.
1306   1306  
1307   @par Complexity 1307   @par Complexity
1308   Constant. 1308   Constant.
1309   1309  
1310   @par Exception Safety 1310   @par Exception Safety
1311   No-throw guarantee. 1311   No-throw guarantee.
1312   */ 1312   */
1313   bool 1313   bool
HITCBC 1314   148 is_null() const noexcept 1314   148 is_null() const noexcept
1315   { 1315   {
HITCBC 1316   148 return kind() == json::kind::null; 1316   148 return kind() == json::kind::null;
1317   } 1317   }
1318   1318  
1319   /** Checks if this is an @ref array or an @ref object. 1319   /** Checks if this is an @ref array or an @ref object.
1320   1320  
1321   This function returns `true` if @ref kind() is either `kind::object` or 1321   This function returns `true` if @ref kind() is either `kind::object` or
1322   `kind::array`. 1322   `kind::array`.
1323   1323  
1324   @par Complexity 1324   @par Complexity
1325   Constant. 1325   Constant.
1326   1326  
1327   @par Exception Safety 1327   @par Exception Safety
1328   No-throw guarantee. 1328   No-throw guarantee.
1329   */ 1329   */
1330   bool 1330   bool
HITCBC 1331   8 is_structured() const noexcept 1331   8 is_structured() const noexcept
1332   { 1332   {
1333   // VFALCO Could use bit 0x20 for this 1333   // VFALCO Could use bit 0x20 for this
1334   return 1334   return
HITCBC 1335   15 kind() == json::kind::object || 1335   15 kind() == json::kind::object ||
HITCBC 1336   15 kind() == json::kind::array; 1336   15 kind() == json::kind::array;
1337   } 1337   }
1338   1338  
1339   /** Check if this is not an @ref array or @ref object. 1339   /** Check if this is not an @ref array or @ref object.
1340   1340  
1341   This function returns `true` if @ref kind() is neither `kind::object` 1341   This function returns `true` if @ref kind() is neither `kind::object`
1342   nor `kind::array`. 1342   nor `kind::array`.
1343   1343  
1344   @par Complexity 1344   @par Complexity
1345   Constant. 1345   Constant.
1346   1346  
1347   @par Exception Safety 1347   @par Exception Safety
1348   No-throw guarantee. 1348   No-throw guarantee.
1349   */ 1349   */
1350   bool 1350   bool
HITCBC 1351   8 is_primitive() const noexcept 1351   8 is_primitive() const noexcept
1352   { 1352   {
1353   // VFALCO Could use bit 0x20 for this 1353   // VFALCO Could use bit 0x20 for this
1354   return 1354   return
HITCBC 1355   15 sca_.k != json::kind::object && 1355   15 sca_.k != json::kind::object &&
HITCBC 1356   15 sca_.k != json::kind::array; 1356   15 sca_.k != json::kind::array;
1357   } 1357   }
1358   1358  
1359   /** Check if this is a number. 1359   /** Check if this is a number.
1360   1360  
1361   This function returns `true` when @ref kind() is one of `kind::int64`, 1361   This function returns `true` when @ref kind() is one of `kind::int64`,
1362   `kind::uint64`, or `kind::double_`. 1362   `kind::uint64`, or `kind::double_`.
1363   1363  
1364   @par Complexity 1364   @par Complexity
1365   Constant. 1365   Constant.
1366   1366  
1367   @par Exception Safety 1367   @par Exception Safety
1368   No-throw guarantee. 1368   No-throw guarantee.
1369   */ 1369   */
1370   bool 1370   bool
HITCBC 1371   83 is_number() const noexcept 1371   83 is_number() const noexcept
1372   { 1372   {
1373   // VFALCO Could use bit 0x40 for this 1373   // VFALCO Could use bit 0x40 for this
1374   return 1374   return
HITCBC 1375   92 kind() == json::kind::int64 || 1375   92 kind() == json::kind::int64 ||
HITCBC 1376   92 kind() == json::kind::uint64 || 1376   92 kind() == json::kind::uint64 ||
HITCBC 1377   91 kind() == json::kind::double_; 1377   91 kind() == json::kind::double_;
1378   } 1378   }
1379   1379  
1380   //------------------------------------------------------ 1380   //------------------------------------------------------
1381   1381  
1382   /** Return a pointer to the underlying @ref array. 1382   /** Return a pointer to the underlying @ref array.
1383   1383  
1384   If `this->kind() == kind::array`, returns a pointer to the underlying 1384   If `this->kind() == kind::array`, returns a pointer to the underlying
1385   array. Otherwise, returns `nullptr`. 1385   array. Otherwise, returns `nullptr`.
1386   1386  
1387   @par Example 1387   @par Example
1388   The return value is used in both a boolean context and 1388   The return value is used in both a boolean context and
1389   to assign a variable: 1389   to assign a variable:
1390   @code 1390   @code
1391   if( auto p = jv.if_array() ) 1391   if( auto p = jv.if_array() )
1392   return *p; 1392   return *p;
1393   @endcode 1393   @endcode
1394   1394  
1395   @par Complexity 1395   @par Complexity
1396   Constant. 1396   Constant.
1397   1397  
1398   @par Exception Safety 1398   @par Exception Safety
1399   No-throw guarantee. 1399   No-throw guarantee.
1400   1400  
1401   @{ 1401   @{
1402   */ 1402   */
1403   array const* 1403   array const*
HITCBC 1404   260 if_array() const noexcept 1404   260 if_array() const noexcept
1405   { 1405   {
HITCBC 1406   260 if(kind() == json::kind::array) 1406   260 if(kind() == json::kind::array)
HITCBC 1407   223 return &arr_; 1407   223 return &arr_;
HITCBC 1408   37 return nullptr; 1408   37 return nullptr;
1409   } 1409   }
1410   1410  
1411   array* 1411   array*
HITCBC 1412   12 if_array() noexcept 1412   12 if_array() noexcept
1413   { 1413   {
HITCBC 1414   12 if(kind() == json::kind::array) 1414   12 if(kind() == json::kind::array)
HITCBC 1415   5 return &arr_; 1415   5 return &arr_;
HITCBC 1416   7 return nullptr; 1416   7 return nullptr;
1417   } 1417   }
1418   /// @} 1418   /// @}
1419   1419  
1420   /** Return a pointer to the underlying @ref object. 1420   /** Return a pointer to the underlying @ref object.
1421   1421  
1422   If `this->kind() == kind::object`, returns a pointer to the underlying 1422   If `this->kind() == kind::object`, returns a pointer to the underlying
1423   object. Otherwise, returns `nullptr`. 1423   object. Otherwise, returns `nullptr`.
1424   1424  
1425   @par Example 1425   @par Example
1426   The return value is used in both a boolean context and 1426   The return value is used in both a boolean context and
1427   to assign a variable: 1427   to assign a variable:
1428   @code 1428   @code
1429   if( auto p = jv.if_object() ) 1429   if( auto p = jv.if_object() )
1430   return *p; 1430   return *p;
1431   @endcode 1431   @endcode
1432   1432  
1433   @par Complexity 1433   @par Complexity
1434   Constant. 1434   Constant.
1435   1435  
1436   @par Exception Safety 1436   @par Exception Safety
1437   No-throw guarantee. 1437   No-throw guarantee.
1438   1438  
1439   @{ 1439   @{
1440   */ 1440   */
1441   object const* 1441   object const*
HITCBC 1442   94 if_object() const noexcept 1442   94 if_object() const noexcept
1443   { 1443   {
HITCBC 1444   94 if(kind() == json::kind::object) 1444   94 if(kind() == json::kind::object)
HITCBC 1445   69 return &obj_; 1445   69 return &obj_;
HITCBC 1446   25 return nullptr; 1446   25 return nullptr;
1447   } 1447   }
1448   1448  
1449   object* 1449   object*
HITCBC 1450   13 if_object() noexcept 1450   13 if_object() noexcept
1451   { 1451   {
HITCBC 1452   13 if(kind() == json::kind::object) 1452   13 if(kind() == json::kind::object)
HITCBC 1453   6 return &obj_; 1453   6 return &obj_;
HITCBC 1454   7 return nullptr; 1454   7 return nullptr;
1455   } 1455   }
1456   /// @} 1456   /// @}
1457   1457  
1458   /** Return a pointer to the underlying @ref string. 1458   /** Return a pointer to the underlying @ref string.
1459   1459  
1460   If `this->kind() == kind::string`, returns a pointer to the underlying 1460   If `this->kind() == kind::string`, returns a pointer to the underlying
1461   object. Otherwise, returns `nullptr`. 1461   object. Otherwise, returns `nullptr`.
1462   1462  
1463   @par Example 1463   @par Example
1464   The return value is used in both a boolean context and 1464   The return value is used in both a boolean context and
1465   to assign a variable: 1465   to assign a variable:
1466   @code 1466   @code
1467   if( auto p = jv.if_string() ) 1467   if( auto p = jv.if_string() )
1468   return *p; 1468   return *p;
1469   @endcode 1469   @endcode
1470   1470  
1471   @par Complexity 1471   @par Complexity
1472   Constant. 1472   Constant.
1473   1473  
1474   @par Exception Safety 1474   @par Exception Safety
1475   No-throw guarantee. 1475   No-throw guarantee.
1476   1476  
1477   @{ 1477   @{
1478   */ 1478   */
1479   string const* 1479   string const*
HITCBC 1480   252 if_string() const noexcept 1480   252 if_string() const noexcept
1481   { 1481   {
HITCBC 1482   252 if(kind() == json::kind::string) 1482   252 if(kind() == json::kind::string)
HITCBC 1483   184 return &str_; 1483   184 return &str_;
HITCBC 1484   68 return nullptr; 1484   68 return nullptr;
1485   } 1485   }
1486   1486  
1487   string* 1487   string*
HITCBC 1488   13 if_string() noexcept 1488   13 if_string() noexcept
1489   { 1489   {
HITCBC 1490   13 if(kind() == json::kind::string) 1490   13 if(kind() == json::kind::string)
HITCBC 1491   6 return &str_; 1491   6 return &str_;
HITCBC 1492   7 return nullptr; 1492   7 return nullptr;
1493   } 1493   }
1494   /// @} 1494   /// @}
1495   1495  
1496   /** Return a pointer to the underlying `std::int64_t`. 1496   /** Return a pointer to the underlying `std::int64_t`.
1497   1497  
1498   If `this->kind() == kind::int64`, returns a pointer to the underlying 1498   If `this->kind() == kind::int64`, returns a pointer to the underlying
1499   integer. Otherwise, returns `nullptr`. 1499   integer. Otherwise, returns `nullptr`.
1500   1500  
1501   @par Example 1501   @par Example
1502   The return value is used in both a boolean context and 1502   The return value is used in both a boolean context and
1503   to assign a variable: 1503   to assign a variable:
1504   @code 1504   @code
1505   if( auto p = jv.if_int64() ) 1505   if( auto p = jv.if_int64() )
1506   return *p; 1506   return *p;
1507   @endcode 1507   @endcode
1508   1508  
1509   @par Complexity 1509   @par Complexity
1510   Constant. 1510   Constant.
1511   1511  
1512   @par Exception Safety 1512   @par Exception Safety
1513   No-throw guarantee. 1513   No-throw guarantee.
1514   1514  
1515   @{ 1515   @{
1516   */ 1516   */
1517   std::int64_t const* 1517   std::int64_t const*
HITCBC 1518   8 if_int64() const noexcept 1518   8 if_int64() const noexcept
1519   { 1519   {
HITCBC 1520   8 if(kind() == json::kind::int64) 1520   8 if(kind() == json::kind::int64)
HITCBC 1521   1 return &sca_.i; 1521   1 return &sca_.i;
HITCBC 1522   7 return nullptr; 1522   7 return nullptr;
1523   } 1523   }
1524   1524  
1525   std::int64_t* 1525   std::int64_t*
HITCBC 1526   13 if_int64() noexcept 1526   13 if_int64() noexcept
1527   { 1527   {
HITCBC 1528   13 if(kind() == json::kind::int64) 1528   13 if(kind() == json::kind::int64)
HITCBC 1529   6 return &sca_.i; 1529   6 return &sca_.i;
HITCBC 1530   7 return nullptr; 1530   7 return nullptr;
1531   } 1531   }
1532   /// @} 1532   /// @}
1533   1533  
1534   /** Return a pointer to the underlying `std::uint64_t`. 1534   /** Return a pointer to the underlying `std::uint64_t`.
1535   1535  
1536   If `this->kind() == kind::uint64`, returns a pointer to the underlying 1536   If `this->kind() == kind::uint64`, returns a pointer to the underlying
1537   unsigned integer. Otherwise, returns `nullptr`. 1537   unsigned integer. Otherwise, returns `nullptr`.
1538   1538  
1539   @par Example 1539   @par Example
1540   The return value is used in both a boolean context and 1540   The return value is used in both a boolean context and
1541   to assign a variable: 1541   to assign a variable:
1542   @code 1542   @code
1543   if( auto p = jv.if_uint64() ) 1543   if( auto p = jv.if_uint64() )
1544   return *p; 1544   return *p;
1545   @endcode 1545   @endcode
1546   1546  
1547   @par Complexity 1547   @par Complexity
1548   Constant. 1548   Constant.
1549   1549  
1550   @par Exception Safety 1550   @par Exception Safety
1551   No-throw guarantee. 1551   No-throw guarantee.
1552   1552  
1553   @{ 1553   @{
1554   */ 1554   */
1555   std::uint64_t const* 1555   std::uint64_t const*
HITCBC 1556   8 if_uint64() const noexcept 1556   8 if_uint64() const noexcept
1557   { 1557   {
HITCBC 1558   8 if(kind() == json::kind::uint64) 1558   8 if(kind() == json::kind::uint64)
HITCBC 1559   1 return &sca_.u; 1559   1 return &sca_.u;
HITCBC 1560   7 return nullptr; 1560   7 return nullptr;
1561   } 1561   }
1562   1562  
1563   std::uint64_t* 1563   std::uint64_t*
HITCBC 1564   11 if_uint64() noexcept 1564   11 if_uint64() noexcept
1565   { 1565   {
HITCBC 1566   11 if(kind() == json::kind::uint64) 1566   11 if(kind() == json::kind::uint64)
HITCBC 1567   4 return &sca_.u; 1567   4 return &sca_.u;
HITCBC 1568   7 return nullptr; 1568   7 return nullptr;
1569   } 1569   }
1570   /// @} 1570   /// @}
1571   1571  
1572   /** Return a pointer to the underlying `double`. 1572   /** Return a pointer to the underlying `double`.
1573   1573  
1574   If `this->kind() == kind::double_`, returns a pointer to the underlying 1574   If `this->kind() == kind::double_`, returns a pointer to the underlying
1575   double. Otherwise, returns `nullptr`. 1575   double. Otherwise, returns `nullptr`.
1576   1576  
1577   @par Example 1577   @par Example
1578   The return value is used in both a boolean context and 1578   The return value is used in both a boolean context and
1579   to assign a variable: 1579   to assign a variable:
1580   @code 1580   @code
1581   if( auto p = jv.if_double() ) 1581   if( auto p = jv.if_double() )
1582   return *p; 1582   return *p;
1583   @endcode 1583   @endcode
1584   1584  
1585   @par Complexity 1585   @par Complexity
1586   Constant. 1586   Constant.
1587   1587  
1588   @par Exception Safety 1588   @par Exception Safety
1589   No-throw guarantee. 1589   No-throw guarantee.
1590   1590  
1591   @{ 1591   @{
1592   */ 1592   */
1593   double const* 1593   double const*
HITCBC 1594   8 if_double() const noexcept 1594   8 if_double() const noexcept
1595   { 1595   {
HITCBC 1596   8 if(kind() == json::kind::double_) 1596   8 if(kind() == json::kind::double_)
HITCBC 1597   1 return &sca_.d; 1597   1 return &sca_.d;
HITCBC 1598   7 return nullptr; 1598   7 return nullptr;
1599   } 1599   }
1600   1600  
1601   double* 1601   double*
HITCBC 1602   11 if_double() noexcept 1602   11 if_double() noexcept
1603   { 1603   {
HITCBC 1604   11 if(kind() == json::kind::double_) 1604   11 if(kind() == json::kind::double_)
HITCBC 1605   4 return &sca_.d; 1605   4 return &sca_.d;
HITCBC 1606   7 return nullptr; 1606   7 return nullptr;
1607   } 1607   }
1608   /// @} 1608   /// @}
1609   1609  
1610   /** Return a pointer to the underlying `bool` . 1610   /** Return a pointer to the underlying `bool` .
1611   1611  
1612   If `this->kind() == kind::bool_`, returns a pointer to the underlying 1612   If `this->kind() == kind::bool_`, returns a pointer to the underlying
1613   boolean. Otherwise, returns `nullptr`. 1613   boolean. Otherwise, returns `nullptr`.
1614   1614  
1615   @par Example 1615   @par Example
1616   The return value is used in both a boolean context and 1616   The return value is used in both a boolean context and
1617   to assign a variable: 1617   to assign a variable:
1618   @code 1618   @code
1619   if( auto p = jv.if_bool() ) 1619   if( auto p = jv.if_bool() )
1620   return *p; 1620   return *p;
1621   @endcode 1621   @endcode
1622   1622  
1623   @par Complexity 1623   @par Complexity
1624   Constant. 1624   Constant.
1625   1625  
1626   @par Exception Safety 1626   @par Exception Safety
1627   No-throw guarantee. 1627   No-throw guarantee.
1628   1628  
1629   @{ 1629   @{
1630   */ 1630   */
1631   bool const* 1631   bool const*
HITCBC 1632   57 if_bool() const noexcept 1632   57 if_bool() const noexcept
1633   { 1633   {
HITCBC 1634   57 if(kind() == json::kind::bool_) 1634   57 if(kind() == json::kind::bool_)
HITCBC 1635   43 return &sca_.b; 1635   43 return &sca_.b;
HITCBC 1636   14 return nullptr; 1636   14 return nullptr;
1637   } 1637   }
1638   1638  
1639   bool* 1639   bool*
HITCBC 1640   11 if_bool() noexcept 1640   11 if_bool() noexcept
1641   { 1641   {
HITCBC 1642   11 if(kind() == json::kind::bool_) 1642   11 if(kind() == json::kind::bool_)
HITCBC 1643   4 return &sca_.b; 1643   4 return &sca_.b;
HITCBC 1644   7 return nullptr; 1644   7 return nullptr;
1645   } 1645   }
1646   /// @} 1646   /// @}
1647   1647  
1648   //------------------------------------------------------ 1648   //------------------------------------------------------
1649   1649  
1650   /** Return the stored number cast to an arithmetic type. 1650   /** Return the stored number cast to an arithmetic type.
1651   1651  
1652   This function attempts to return the stored value converted to the 1652   This function attempts to return the stored value converted to the
1653   arithmetic type `T` which may not be `bool`: 1653   arithmetic type `T` which may not be `bool`:
1654   1654  
1655   @li If `T` is an integral type and the stored value is a number which 1655   @li If `T` is an integral type and the stored value is a number which
1656   can be losslessly converted, the conversion is performed without 1656   can be losslessly converted, the conversion is performed without
1657   error and the converted number is returned. 1657   error and the converted number is returned.
1658   @li If `T` is an integral type and the stored value is a number which 1658   @li If `T` is an integral type and the stored value is a number which
1659   cannot be losslessly converted, then the operation fails with 1659   cannot be losslessly converted, then the operation fails with
1660   an error. 1660   an error.
1661   @li If `T` is a floating point type and the stored value is a number, 1661   @li If `T` is a floating point type and the stored value is a number,
1662   the conversion is performed without error. The converted number is 1662   the conversion is performed without error. The converted number is
1663   returned, with a possible loss of precision. 1663   returned, with a possible loss of precision.
1664   @li Otherwise, if the stored value is not a number; that is, if 1664   @li Otherwise, if the stored value is not a number; that is, if
1665   @ref is_number() returns `false`, then the operation fails with 1665   @ref is_number() returns `false`, then the operation fails with
1666   an error. 1666   an error.
1667   1667  
1668   @par Constraints 1668   @par Constraints
1669   @code 1669   @code
1670   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value 1670   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1671   @endcode 1671   @endcode
1672   1672  
1673   @par Complexity 1673   @par Complexity
1674   Constant. 1674   Constant.
1675   1675  
1676   @par Exception Safety 1676   @par Exception Safety
1677   @li **(1)**, **(2)** no-throw guarantee. 1677   @li **(1)**, **(2)** no-throw guarantee.
1678   @li **(3)** strong guarantee. 1678   @li **(3)** strong guarantee.
1679   1679  
1680   @return The converted number. 1680   @return The converted number.
1681   1681  
1682   @param ec Set to the error, if any occurred. 1682   @param ec Set to the error, if any occurred.
1683   1683  
1684   @return The converted number. 1684   @return The converted number.
1685   1685  
1686   @{ 1686   @{
1687   */ 1687   */
1688   template<class T> 1688   template<class T>
1689   #ifdef BOOST_JSON_DOCS 1689   #ifdef BOOST_JSON_DOCS
1690   T 1690   T
1691   #else 1691   #else
1692   typename std::enable_if< 1692   typename std::enable_if<
1693   std::is_arithmetic<T>::value && 1693   std::is_arithmetic<T>::value &&
1694   ! std::is_same<T, bool>::value, 1694   ! std::is_same<T, bool>::value,
1695   T>::type 1695   T>::type
1696   #endif 1696   #endif
HITCBC 1697   3594 to_number(system::error_code& ec) const noexcept 1697   3594 to_number(system::error_code& ec) const noexcept
1698   { 1698   {
1699   error e; 1699   error e;
HITCBC 1700   3594 auto result = to_number<T>(e); 1700   3594 auto result = to_number<T>(e);
HITCBC 1701   3594 BOOST_JSON_FAIL(ec, e); 1701   3594 BOOST_JSON_FAIL(ec, e);
HITCBC 1702   3594 return result; 1702   3594 return result;
1703   } 1703   }
1704   1704  
1705   template<class T> 1705   template<class T>
1706   #ifdef BOOST_JSON_DOCS 1706   #ifdef BOOST_JSON_DOCS
1707   T 1707   T
1708   #else 1708   #else
1709   typename std::enable_if< 1709   typename std::enable_if<
1710   std::is_arithmetic<T>::value && 1710   std::is_arithmetic<T>::value &&
1711   ! std::is_same<T, bool>::value, 1711   ! std::is_same<T, bool>::value,
1712   T>::type 1712   T>::type
1713   #endif 1713   #endif
HITCBC 1714   1 to_number(std::error_code& ec) const noexcept 1714   1 to_number(std::error_code& ec) const noexcept
1715   { 1715   {
HITCBC 1716   1 system::error_code jec; 1716   1 system::error_code jec;
HITCBC 1717   1 auto result = to_number<T>(jec); 1717   1 auto result = to_number<T>(jec);
HITCBC 1718   1 ec = jec; 1718   1 ec = jec;
HITCBC 1719   1 return result; 1719   1 return result;
1720   } 1720   }
1721   1721  
1722   /** Overload 1722   /** Overload
1723   1723  
  1724 + @param loc @ref boost::source_location to use in thrown exception; the
  1725 + source location of the call site by default.
  1726 +
1724   @throws boost::system::system_error Overload **(3)** reports errors by 1727   @throws boost::system::system_error Overload **(3)** reports errors by
1725   throwing an exception. 1728   throwing an exception.
1726   */ 1729   */
1727   template<class T> 1730   template<class T>
1728   #ifdef BOOST_JSON_DOCS 1731   #ifdef BOOST_JSON_DOCS
1729   T 1732   T
1730   #else 1733   #else
1731   typename std::enable_if< 1734   typename std::enable_if<
1732   std::is_arithmetic<T>::value && 1735   std::is_arithmetic<T>::value &&
1733   ! std::is_same<T, bool>::value, 1736   ! std::is_same<T, bool>::value,
1734   T>::type 1737   T>::type
1735   #endif 1738   #endif
HITCBC 1736 - 194 to_number() const 1739 + 194 to_number(source_location const& loc = BOOST_CURRENT_LOCATION) const
1737   { 1740   {
HITCBC 1738 - 194 return try_to_number<T>().value(); 1741 + 194 return try_to_number<T>().value(loc);
1739   } 1742   }
1740   /// @} 1743   /// @}
1741   1744  
1742   /** Return the stored number as @ref boost::system::result. 1745   /** Return the stored number as @ref boost::system::result.
1743   1746  
1744   This function attempts to return the stored value converted to the 1747   This function attempts to return the stored value converted to the
1745   arithmetic type `T` which may not be `bool`: 1748   arithmetic type `T` which may not be `bool`:
1746   1749  
1747   @li If `T` is an integral type and the stored value is a number which 1750   @li If `T` is an integral type and the stored value is a number which
1748   can be losslessly converted, the conversion is performed without 1751   can be losslessly converted, the conversion is performed without
1749   error and `result<T>` containing the converted number is returned. 1752   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 1753   @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 1754   cannot be losslessly converted, then `result<T>` containing the
1752   corresponding `error_code` is returned. 1755   corresponding `error_code` is returned.
1753   @li If `T` is a floating point type and the stored value is a number, 1756   @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 1757   the conversion is performed without error. `result<T>` containing
1755   the converted number, with a possible loss of precision, is 1758   the converted number, with a possible loss of precision, is
1756   returned. 1759   returned.
1757   @li Otherwise, if the stored value is not a number; that is, if 1760   @li Otherwise, if the stored value is not a number; that is, if
1758   `this->is_number()` returns `false`, then `result<T>` containing 1761   `this->is_number()` returns `false`, then `result<T>` containing
1759   the corresponding `error_code` is returned. 1762   the corresponding `error_code` is returned.
1760   1763  
1761   @par Constraints 1764   @par Constraints
1762   @code 1765   @code
1763   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value 1766   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1764   @endcode 1767   @endcode
1765   1768  
1766   @par Complexity 1769   @par Complexity
1767   Constant. 1770   Constant.
1768   1771  
1769   @par Exception Safety 1772   @par Exception Safety
1770   No-throw guarantee. 1773   No-throw guarantee.
1771   1774  
1772   @return `boost::system::result<T>` with either the converted number or 1775   @return `boost::system::result<T>` with either the converted number or
1773   an `error_code`. 1776   an `error_code`.
1774   */ 1777   */
1775   template<class T> 1778   template<class T>
1776   #ifdef BOOST_JSON_DOCS 1779   #ifdef BOOST_JSON_DOCS
1777   system::result<T> 1780   system::result<T>
1778   #else 1781   #else
1779   typename std::enable_if< 1782   typename std::enable_if<
1780   std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value, 1783   std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
1781   system::result<T> 1784   system::result<T>
1782   >::type 1785   >::type
1783   #endif 1786   #endif
HITCBC 1784   196 try_to_number() const noexcept 1787   196 try_to_number() const noexcept
1785   { 1788   {
HITCBC 1786   196 system::error_code ec; 1789   196 system::error_code ec;
HITCBC 1787   196 T result = to_number<T>(ec); 1790   196 T result = to_number<T>(ec);
HITCBC 1788   196 if( ec ) 1791   196 if( ec )
HITCBC 1789   78 return {system::in_place_error, ec}; 1792   78 return {system::in_place_error, ec};
1790   1793  
HITCBC 1791   118 return {system::in_place_value, result}; 1794   118 return {system::in_place_value, result};
1792   } 1795   }
1793   1796  
1794   //------------------------------------------------------ 1797   //------------------------------------------------------
1795   // 1798   //
1796   // Accessors 1799   // Accessors
1797   // 1800   //
1798   //------------------------------------------------------ 1801   //------------------------------------------------------
1799   1802  
1800   /** Return the associated memory resource. 1803   /** Return the associated memory resource.
1801   1804  
1802   This function returns a smart pointer to the 1805   This function returns a smart pointer to the
1803   @ref boost::container::pmr::memory_resource used by the container. 1806   @ref boost::container::pmr::memory_resource used by the container.
1804   1807  
1805   @par Complexity 1808   @par Complexity
1806   Constant. 1809   Constant.
1807   1810  
1808   @par Exception Safety 1811   @par Exception Safety
1809   No-throw guarantee. 1812   No-throw guarantee.
1810   */ 1813   */
1811   storage_ptr const& 1814   storage_ptr const&
HITCBC 1812   75892 storage() const noexcept 1815   75892 storage() const noexcept
1813   { 1816   {
HITCBC 1814   75892 return sp_; 1817   75892 return sp_;
1815   } 1818   }
1816   1819  
1817   /** Return the associated allocator. 1820   /** Return the associated allocator.
1818   1821  
1819   This function returns an instance of @ref allocator_type constructed 1822   This function returns an instance of @ref allocator_type constructed
1820   from the associated @ref boost::container::pmr::memory_resource. 1823   from the associated @ref boost::container::pmr::memory_resource.
1821   1824  
1822   @par Complexity 1825   @par Complexity
1823   Constant. 1826   Constant.
1824   1827  
1825   @par Exception Safety 1828   @par Exception Safety
1826   No-throw guarantee. 1829   No-throw guarantee.
1827   */ 1830   */
1828   allocator_type 1831   allocator_type
HITCBC 1829   1 get_allocator() const noexcept 1832   1 get_allocator() const noexcept
1830   { 1833   {
HITCBC 1831   1 return sp_.get(); 1834   1 return sp_.get();
1832   } 1835   }
1833   1836  
1834   //------------------------------------------------------ 1837   //------------------------------------------------------
1835   1838  
1836   /** Return `result` with a reference to the underlying @ref array 1839   /** Return `result` with a reference to the underlying @ref array
1837   1840  
1838   If @ref is_array() is `true`, the result contains a reference to the 1841   If @ref is_array() is `true`, the result contains a reference to the
1839   underlying @ref array, otherwise it contains an `error_code`. 1842   underlying @ref array, otherwise it contains an `error_code`.
1840   1843  
1841   @par Example 1844   @par Example
1842   The return value can be used in both a boolean context and 1845   The return value can be used in both a boolean context and
1843   to assign a variable: 1846   to assign a variable:
1844   @code 1847   @code
1845   if( auto r = jv.try_as_array() ) 1848   if( auto r = jv.try_as_array() )
1846   return *r; 1849   return *r;
1847   @endcode 1850   @endcode
1848   1851  
1849   But can also be used to throw an exception on error: 1852   But can also be used to throw an exception on error:
1850   @code 1853   @code
1851   return jv.try_as_array().value(); 1854   return jv.try_as_array().value();
1852   @endcode 1855   @endcode
1853   1856  
1854   @par Complexity 1857   @par Complexity
1855   Constant. 1858   Constant.
1856   1859  
1857   @par Exception Safety 1860   @par Exception Safety
1858   No-throw guarantee. 1861   No-throw guarantee.
1859   1862  
1860   @{ 1863   @{
1861   */ 1864   */
1862   BOOST_JSON_DECL 1865   BOOST_JSON_DECL
1863   system::result<array&> 1866   system::result<array&>
1864   try_as_array() noexcept; 1867   try_as_array() noexcept;
1865   1868  
1866   BOOST_JSON_DECL 1869   BOOST_JSON_DECL
1867   system::result<array const&> 1870   system::result<array const&>
1868   try_as_array() const noexcept; 1871   try_as_array() const noexcept;
1869   /// @} 1872   /// @}
1870   1873  
1871   /** Return `result` with a reference to the underlying @ref object. 1874   /** Return `result` with a reference to the underlying @ref object.
1872   1875  
1873   If @ref is_object() is `true`, the result contains a reference to the 1876   If @ref is_object() is `true`, the result contains a reference to the
1874   underlying @ref object, otherwise it contains an `error_code`. 1877   underlying @ref object, otherwise it contains an `error_code`.
1875   1878  
1876   @par Example 1879   @par Example
1877   The return value can be used in both a boolean context and 1880   The return value can be used in both a boolean context and
1878   to assign a variable: 1881   to assign a variable:
1879   @code 1882   @code
1880   if( auto r = jv.try_as_object() ) 1883   if( auto r = jv.try_as_object() )
1881   return *r; 1884   return *r;
1882   @endcode 1885   @endcode
1883   1886  
1884   But can also be used to throw an exception on error: 1887   But can also be used to throw an exception on error:
1885   @code 1888   @code
1886   return jv.try_as_object().value(); 1889   return jv.try_as_object().value();
1887   @endcode 1890   @endcode
1888   1891  
1889   @par Complexity 1892   @par Complexity
1890   Constant. 1893   Constant.
1891   1894  
1892   @par Exception Safety 1895   @par Exception Safety
1893   No-throw guarantee. 1896   No-throw guarantee.
1894   1897  
1895   @{ 1898   @{
1896   */ 1899   */
1897   BOOST_JSON_DECL 1900   BOOST_JSON_DECL
1898   system::result<object&> 1901   system::result<object&>
1899   try_as_object() noexcept; 1902   try_as_object() noexcept;
1900   1903  
1901   BOOST_JSON_DECL 1904   BOOST_JSON_DECL
1902   system::result<object const&> 1905   system::result<object const&>
1903   try_as_object() const noexcept; 1906   try_as_object() const noexcept;
1904   /// @} 1907   /// @}
1905   1908  
1906   /** Return `result` with a reference to the underlying @ref string. 1909   /** Return `result` with a reference to the underlying @ref string.
1907   1910  
1908   If @ref is_string() is `true`, the result contains a reference to the 1911   If @ref is_string() is `true`, the result contains a reference to the
1909   underlying @ref string, otherwise it contains an `error_code`. 1912   underlying @ref string, otherwise it contains an `error_code`.
1910   1913  
1911   @par Example 1914   @par Example
1912   The return value can be used in both a boolean context and 1915   The return value can be used in both a boolean context and
1913   to assign a variable: 1916   to assign a variable:
1914   @code 1917   @code
1915   if( auto r = jv.try_as_string() ) 1918   if( auto r = jv.try_as_string() )
1916   return *r; 1919   return *r;
1917   @endcode 1920   @endcode
1918   1921  
1919   But can also be used to throw an exception on error: 1922   But can also be used to throw an exception on error:
1920   @code 1923   @code
1921   return jv.try_as_string().value(); 1924   return jv.try_as_string().value();
1922   @endcode 1925   @endcode
1923   1926  
1924   @par Complexity 1927   @par Complexity
1925   Constant. 1928   Constant.
1926   1929  
1927   @par Exception Safety 1930   @par Exception Safety
1928   No-throw guarantee. 1931   No-throw guarantee.
1929   1932  
1930   @{ 1933   @{
1931   */ 1934   */
1932   BOOST_JSON_DECL 1935   BOOST_JSON_DECL
1933   system::result<string&> 1936   system::result<string&>
1934   try_as_string() noexcept; 1937   try_as_string() noexcept;
1935   1938  
1936   BOOST_JSON_DECL 1939   BOOST_JSON_DECL
1937   system::result<string const&> 1940   system::result<string const&>
1938   try_as_string() const noexcept; 1941   try_as_string() const noexcept;
1939   /// @} 1942   /// @}
1940   1943  
1941   /** Return `result` with the underlying `std::int64_t` 1944   /** Return `result` with the underlying `std::int64_t`
1942   1945  
1943   If @ref is_int64() is `true`, the result contains a reference to **(1)** 1946   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 1947   or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1945   contains an `error_code`. 1948   contains an `error_code`.
1946   1949  
1947   @par Example 1950   @par Example
1948   The return value can be used in both a boolean context and 1951   The return value can be used in both a boolean context and
1949   to assign a variable: 1952   to assign a variable:
1950   @code 1953   @code
1951   if( auto r = jv.try_as_int64() ) 1954   if( auto r = jv.try_as_int64() )
1952   return *r; 1955   return *r;
1953   @endcode 1956   @endcode
1954   1957  
1955   But can also be used to throw an exception on error: 1958   But can also be used to throw an exception on error:
1956   @code 1959   @code
1957   return jv.try_as_int64().value(); 1960   return jv.try_as_int64().value();
1958   @endcode 1961   @endcode
1959   1962  
1960   @par Complexity 1963   @par Complexity
1961   Constant. 1964   Constant.
1962   1965  
1963   @par Exception Safety 1966   @par Exception Safety
1964   No-throw guarantee. 1967   No-throw guarantee.
1965   1968  
1966   @{ 1969   @{
1967   */ 1970   */
1968   BOOST_JSON_DECL 1971   BOOST_JSON_DECL
1969   system::result<std::int64_t&> 1972   system::result<std::int64_t&>
1970   try_as_int64() noexcept; 1973   try_as_int64() noexcept;
1971   1974  
1972   BOOST_JSON_DECL 1975   BOOST_JSON_DECL
1973   system::result<std::int64_t> 1976   system::result<std::int64_t>
1974   try_as_int64() const noexcept; 1977   try_as_int64() const noexcept;
1975   /// @} 1978   /// @}
1976   1979  
1977   /** Return `result` with the underlying `std::uint64_t`. 1980   /** Return `result` with the underlying `std::uint64_t`.
1978   1981  
1979   If @ref is_uint64() is `true`, the result contains a reference to **(1)** 1982   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 1983   or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1981   contains an `error_code`. 1984   contains an `error_code`.
1982   1985  
1983   @par Example 1986   @par Example
1984   The return value can be used in both a boolean context and 1987   The return value can be used in both a boolean context and
1985   to assign a variable: 1988   to assign a variable:
1986   @code 1989   @code
1987   if( auto r = jv.try_as_uint64() ) 1990   if( auto r = jv.try_as_uint64() )
1988   return *r; 1991   return *r;
1989   @endcode 1992   @endcode
1990   1993  
1991   But can also be used to throw an exception on error: 1994   But can also be used to throw an exception on error:
1992   @code 1995   @code
1993   return jv.try_as_uint64().value(); 1996   return jv.try_as_uint64().value();
1994   @endcode 1997   @endcode
1995   1998  
1996   @par Complexity 1999   @par Complexity
1997   Constant. 2000   Constant.
1998   2001  
1999   @par Exception Safety 2002   @par Exception Safety
2000   No-throw guarantee. 2003   No-throw guarantee.
2001   2004  
2002   @{ 2005   @{
2003   */ 2006   */
2004   BOOST_JSON_DECL 2007   BOOST_JSON_DECL
2005   system::result<std::uint64_t&> 2008   system::result<std::uint64_t&>
2006   try_as_uint64() noexcept; 2009   try_as_uint64() noexcept;
2007   2010  
2008   BOOST_JSON_DECL 2011   BOOST_JSON_DECL
2009   system::result<std::uint64_t> 2012   system::result<std::uint64_t>
2010   try_as_uint64() const noexcept; 2013   try_as_uint64() const noexcept;
2011   /// @} 2014   /// @}
2012   2015  
2013   /** Return `result` with the underlying `double` 2016   /** Return `result` with the underlying `double`
2014   2017  
2015   If @ref is_double() is `true`, the result contains a reference to **(1)** 2018   If @ref is_double() is `true`, the result contains a reference to **(1)**
2016   or a copy of **(2)** the underlying `double`, otherwise it 2019   or a copy of **(2)** the underlying `double`, otherwise it
2017   contains an `error_code`. 2020   contains an `error_code`.
2018   2021  
2019   @par Example 2022   @par Example
2020   The return value can be used in both a boolean context and 2023   The return value can be used in both a boolean context and
2021   to assign a variable: 2024   to assign a variable:
2022   @code 2025   @code
2023   if( auto r = jv.try_as_double() ) 2026   if( auto r = jv.try_as_double() )
2024   return *r; 2027   return *r;
2025   @endcode 2028   @endcode
2026   2029  
2027   But can also be used to throw an exception on error: 2030   But can also be used to throw an exception on error:
2028   @code 2031   @code
2029   return jv.try_as_double().value(); 2032   return jv.try_as_double().value();
2030   @endcode 2033   @endcode
2031   2034  
2032   @par Complexity 2035   @par Complexity
2033   Constant. 2036   Constant.
2034   2037  
2035   @par Exception Safety 2038   @par Exception Safety
2036   No-throw guarantee. 2039   No-throw guarantee.
2037   2040  
2038   @{ 2041   @{
2039   */ 2042   */
2040   BOOST_JSON_DECL 2043   BOOST_JSON_DECL
2041   system::result<double&> 2044   system::result<double&>
2042   try_as_double() noexcept; 2045   try_as_double() noexcept;
2043   2046  
2044   BOOST_JSON_DECL 2047   BOOST_JSON_DECL
2045   system::result<double> 2048   system::result<double>
2046   try_as_double() const noexcept; 2049   try_as_double() const noexcept;
2047   /// @} 2050   /// @}
2048   2051  
2049   /** Return `result` with the underlying `bool` 2052   /** Return `result` with the underlying `bool`
2050   2053  
2051   If @ref is_bool() is `true`, the result contains a reference to **(1)** 2054   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 2055   or a copy to **(2)** the underlying `bool`, otherwise it contains an
2053   `error_code`. 2056   `error_code`.
2054   2057  
2055   @par Example 2058   @par Example
2056   The return value can be used in both a boolean context and 2059   The return value can be used in both a boolean context and
2057   to assign a variable: 2060   to assign a variable:
2058   @code 2061   @code
2059   if( auto r = jv.try_as_bool() ) 2062   if( auto r = jv.try_as_bool() )
2060   return *r; 2063   return *r;
2061   @endcode 2064   @endcode
2062   2065  
2063   But can also be used to throw an exception on error: 2066   But can also be used to throw an exception on error:
2064   @code 2067   @code
2065   return jv.try_as_bool().value(); 2068   return jv.try_as_bool().value();
2066   @endcode 2069   @endcode
2067   2070  
2068   @par Complexity 2071   @par Complexity
2069   Constant. 2072   Constant.
2070   2073  
2071   @par Exception Safety 2074   @par Exception Safety
2072   No-throw guarantee. 2075   No-throw guarantee.
2073   2076  
2074   @{ 2077   @{
2075   */ 2078   */
2076   BOOST_JSON_DECL 2079   BOOST_JSON_DECL
2077   system::result<bool&> 2080   system::result<bool&>
2078   try_as_bool() noexcept; 2081   try_as_bool() noexcept;
2079   2082  
2080   BOOST_JSON_DECL 2083   BOOST_JSON_DECL
2081   system::result<bool> 2084   system::result<bool>
2082   try_as_bool() const noexcept; 2085   try_as_bool() const noexcept;
2083   /// @} 2086   /// @}
2084   2087  
2085   /** Return engaged `result` if the `value` is null. 2088   /** Return engaged `result` if the `value` is null.
2086   2089  
2087   If @ref is_null() is `true`, the result is engaged, otherwise it 2090   If @ref is_null() is `true`, the result is engaged, otherwise it
2088   contains an `error_code`. 2091   contains an `error_code`.
2089   2092  
2090   @par Example 2093   @par Example
2091   The return value can be used in both a boolean context and 2094   The return value can be used in both a boolean context and
2092   to assign a variable: 2095   to assign a variable:
2093   @code 2096   @code
2094   if( auto r = jv.try_as_null() ) 2097   if( auto r = jv.try_as_null() )
2095   return *r; 2098   return *r;
2096   @endcode 2099   @endcode
2097   2100  
2098   But can also be used to throw an exception on error: 2101   But can also be used to throw an exception on error:
2099   @code 2102   @code
2100   return jv.try_as_null().value(); 2103   return jv.try_as_null().value();
2101   @endcode 2104   @endcode
2102   2105  
2103   @par Complexity 2106   @par Complexity
2104   Constant. 2107   Constant.
2105   2108  
2106   @par Exception Safety 2109   @par Exception Safety
2107   No-throw guarantee. 2110   No-throw guarantee.
2108   */ 2111   */
2109   BOOST_JSON_DECL 2112   BOOST_JSON_DECL
2110   system::result<std::nullptr_t> 2113   system::result<std::nullptr_t>
2111   try_as_null() const noexcept; 2114   try_as_null() const noexcept;
2112   2115  
2113   //------------------------------------------------------ 2116   //------------------------------------------------------
2114   2117  
2115   /** Return the underlying @ref object, or throw an exception. 2118   /** Return the underlying @ref object, or throw an exception.
2116   2119  
2117   If @ref is_object() is `true`, returns a reference to the underlying 2120   If @ref is_object() is `true`, returns a reference to the underlying
2118   @ref object, otherwise throws an exception. 2121   @ref object, otherwise throws an exception.
2119   2122  
2120   @par Exception Safety 2123   @par Exception Safety
2121   Strong guarantee. 2124   Strong guarantee.
2122   2125  
2123   @throw boost::system::system_error `! this->is_object()`. 2126   @throw boost::system::system_error `! this->is_object()`.
2124   2127  
2125   @param loc @ref boost::source_location to use in thrown exception; the 2128   @param loc @ref boost::source_location to use in thrown exception; the
2126   source location of the call site by default. 2129   source location of the call site by default.
2127   2130  
2128   @par Complexity 2131   @par Complexity
2129   Constant. 2132   Constant.
2130   2133  
2131   @{ 2134   @{
2132   */ 2135   */
2133   object& 2136   object&
HITCBC 2134   167 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) & 2137   167 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2135   { 2138   {
HITCBC 2136   167 auto& self = const_cast<value const&>(*this); 2139   167 auto& self = const_cast<value const&>(*this);
HITCBC 2137   167 return const_cast<object&>( self.as_object(loc) ); 2140   167 return const_cast<object&>( self.as_object(loc) );
2138   } 2141   }
2139   2142  
2140   /// Overload 2143   /// Overload
2141   object&& 2144   object&&
HITCBC 2142   97 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) && 2145   97 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2143   { 2146   {
HITCBC 2144   97 return std::move( as_object(loc) ); 2147   97 return std::move( as_object(loc) );
2145   } 2148   }
2146   2149  
2147   /// Overload 2150   /// Overload
2148   BOOST_JSON_DECL 2151   BOOST_JSON_DECL
2149   object const& 2152   object const&
2150   as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2153   as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2151   /// @} 2154   /// @}
2152   2155  
2153   /** Return the underlying @ref array, or throw an exception. 2156   /** Return the underlying @ref array, or throw an exception.
2154   2157  
2155   If @ref is_array() is `true`, returns a reference to the underlying 2158   If @ref is_array() is `true`, returns a reference to the underlying
2156   @ref array, otherwise throws an exception. 2159   @ref array, otherwise throws an exception.
2157   2160  
2158   @par Exception Safety 2161   @par Exception Safety
2159   Strong guarantee. 2162   Strong guarantee.
2160   2163  
2161   @throw boost::system::system_error `! this->is_array()`. 2164   @throw boost::system::system_error `! this->is_array()`.
2162   2165  
2163   @param loc @ref boost::source_location to use in thrown exception; the 2166   @param loc @ref boost::source_location to use in thrown exception; the
2164   source location of the call site by default. 2167   source location of the call site by default.
2165   2168  
2166   @par Complexity 2169   @par Complexity
2167   Constant. 2170   Constant.
2168   2171  
2169   @{ 2172   @{
2170   */ 2173   */
2171   array& 2174   array&
HITCBC 2172   95 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) & 2175   95 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2173   { 2176   {
HITCBC 2174   95 auto& self = const_cast<value const&>(*this); 2177   95 auto& self = const_cast<value const&>(*this);
HITCBC 2175   95 return const_cast<array&>( self.as_array(loc) ); 2178   95 return const_cast<array&>( self.as_array(loc) );
2176   } 2179   }
2177   2180  
2178   /// Overload 2181   /// Overload
2179   array&& 2182   array&&
HITCBC 2180   10 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) && 2183   10 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2181   { 2184   {
HITCBC 2182   10 return std::move( as_array(loc) ); 2185   10 return std::move( as_array(loc) );
2183   } 2186   }
2184   2187  
2185   /// Overload 2188   /// Overload
2186   BOOST_JSON_DECL 2189   BOOST_JSON_DECL
2187   array const& 2190   array const&
2188   as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2191   as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2189   /// @} 2192   /// @}
2190   2193  
2191   /** Return the underlying @ref string, or throw an exception. 2194   /** Return the underlying @ref string, or throw an exception.
2192   2195  
2193   If @ref is_string() is `true`, returns a reference to the underlying 2196   If @ref is_string() is `true`, returns a reference to the underlying
2194   @ref string, otherwise throws an exception. 2197   @ref string, otherwise throws an exception.
2195   2198  
2196   @par Exception Safety 2199   @par Exception Safety
2197   Strong guarantee. 2200   Strong guarantee.
2198   2201  
2199   @throw boost::system::system_error `! this->is_string()`. 2202   @throw boost::system::system_error `! this->is_string()`.
2200   2203  
2201   @param loc @ref boost::source_location to use in thrown exception; the 2204   @param loc @ref boost::source_location to use in thrown exception; the
2202   source location of the call site by default. 2205   source location of the call site by default.
2203   2206  
2204   @par Complexity 2207   @par Complexity
2205   Constant. 2208   Constant.
2206   2209  
2207   @{ 2210   @{
2208   */ 2211   */
2209   string& 2212   string&
HITCBC 2210   34 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) & 2213   34 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2211   { 2214   {
HITCBC 2212   34 auto& self = const_cast<value const&>(*this); 2215   34 auto& self = const_cast<value const&>(*this);
HITCBC 2213   34 return const_cast<string&>( self.as_string(loc) ); 2216   34 return const_cast<string&>( self.as_string(loc) );
2214   } 2217   }
2215   2218  
2216   /// Overload 2219   /// Overload
2217   string&& 2220   string&&
HITCBC 2218   12 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) && 2221   12 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2219   { 2222   {
HITCBC 2220   12 return std::move( as_string(loc) ); 2223   12 return std::move( as_string(loc) );
2221   } 2224   }
2222   2225  
2223   /// Overload 2226   /// Overload
2224   BOOST_JSON_DECL 2227   BOOST_JSON_DECL
2225   string const& 2228   string const&
2226   as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2229   as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2227   /// @} 2230   /// @}
2228   2231  
2229   /** Return the underlying `std::int64_t`, or throw an exception. 2232   /** Return the underlying `std::int64_t`, or throw an exception.
2230   2233  
2231   If @ref is_int64() is `true`, returns a reference to **(1)** or a copy 2234   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 2235   of **(2)** the underlying `std::int64_t`, otherwise throws an
2233   exception. 2236   exception.
2234   2237  
2235   @note This function is the intended for direct access to the underlying 2238   @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 2239   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 2240   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` 2241   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 2242   has, and you only care about getting a `std::int64_t` number, consider
2240   using @ref to_number instead. 2243   using @ref to_number instead.
2241   2244  
2242   @par Exception Safety 2245   @par Exception Safety
2243   Strong guarantee. 2246   Strong guarantee.
2244   2247  
2245   @throw boost::system::system_error `! this->is_int64()`. 2248   @throw boost::system::system_error `! this->is_int64()`.
2246   2249  
2247   @param loc @ref boost::source_location to use in thrown exception; the 2250   @param loc @ref boost::source_location to use in thrown exception; the
2248   source location of the call site by default. 2251   source location of the call site by default.
2249   2252  
2250   @par Complexity 2253   @par Complexity
2251   Constant. 2254   Constant.
2252   2255  
2253   @{ 2256   @{
2254   */ 2257   */
2255   BOOST_JSON_DECL 2258   BOOST_JSON_DECL
2256   std::int64_t& 2259   std::int64_t&
2257   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION); 2260   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
2258   2261  
2259   /// Overload 2262   /// Overload
2260   BOOST_JSON_DECL 2263   BOOST_JSON_DECL
2261   std::int64_t 2264   std::int64_t
2262   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2265   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2263   /// @} 2266   /// @}
2264   2267  
2265   /** Return the underlying `std::uint64_t`, or throw an exception. 2268   /** Return the underlying `std::uint64_t`, or throw an exception.
2266   2269  
2267   If @ref is_uint64() is `true`, returns a reference to **(1)** or a 2270   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 2271   copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2269   exception. 2272   exception.
2270   2273  
2271   @note This function is intended for direct access to the underlying 2274   @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 2275   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 2276   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` 2277   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 2278   has, and you only care about getting a `std::uint64_t` number, consider
2276   using @ref to_number instead. 2279   using @ref to_number instead.
2277   2280  
2278   @par Exception Safety 2281   @par Exception Safety
2279   Strong guarantee. 2282   Strong guarantee.
2280   2283  
2281   @throw boost::system::system_error `! this->is_uint64()`. 2284   @throw boost::system::system_error `! this->is_uint64()`.
2282   2285  
2283   @param loc @ref boost::source_location to use in thrown exception; the 2286   @param loc @ref boost::source_location to use in thrown exception; the
2284   source location of the call site by default. 2287   source location of the call site by default.
2285   2288  
2286   @par Complexity 2289   @par Complexity
2287   Constant. 2290   Constant.
2288   2291  
2289   @{ 2292   @{
2290   */ 2293   */
2291   BOOST_JSON_DECL 2294   BOOST_JSON_DECL
2292   std::uint64_t& 2295   std::uint64_t&
2293   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION); 2296   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
2294   2297  
2295   /// Overload 2298   /// Overload
2296   BOOST_JSON_DECL 2299   BOOST_JSON_DECL
2297   std::uint64_t 2300   std::uint64_t
2298   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2301   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2299   /// @} 2302   /// @}
2300   2303  
2301   /** Return the underlying `double`, or throw an exception. 2304   /** Return the underlying `double`, or throw an exception.
2302   2305  
2303   If @ref is_double() is `true`, returns a reference to **(1)** or a copy 2306   If @ref is_double() is `true`, returns a reference to **(1)** or a copy
2304   of **(2)** the underlying `double`, otherwise throws an exception. 2307   of **(2)** the underlying `double`, otherwise throws an exception.
2305   2308  
2306   @note This function is intended for direct access to the underlying 2309   @note This function is intended for direct access to the underlying
2307   object, __if__ it has the type `double`. It does not convert the 2310   object, __if__ it has the type `double`. It does not convert the
2308   underlying object to type `double` even if a lossless conversion is 2311   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 2312   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 2313   care about getting a `double` number, consider using @ref to_number
2311   instead. 2314   instead.
2312   2315  
2313   @par Exception Safety 2316   @par Exception Safety
2314   Strong guarantee. 2317   Strong guarantee.
2315   2318  
2316   @throw boost::system::system_error `! this->is_double()`. 2319   @throw boost::system::system_error `! this->is_double()`.
2317   2320  
2318   @param loc @ref boost::source_location to use in thrown exception; the 2321   @param loc @ref boost::source_location to use in thrown exception; the
2319   source location of the call site by default. 2322   source location of the call site by default.
2320   2323  
2321   @par Complexity 2324   @par Complexity
2322   Constant. 2325   Constant.
2323   2326  
2324   @{ 2327   @{
2325   */ 2328   */
2326   BOOST_JSON_DECL 2329   BOOST_JSON_DECL
2327   double& 2330   double&
2328   as_double(source_location const& loc = BOOST_CURRENT_LOCATION); 2331   as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
2329   2332  
2330   /// Overload 2333   /// Overload
2331   BOOST_JSON_DECL 2334   BOOST_JSON_DECL
2332   double 2335   double
2333   as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2336   as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2334   /// @} 2337   /// @}
2335   2338  
2336   /** Return the underlying `bool`, or throw an exception. 2339   /** Return the underlying `bool`, or throw an exception.
2337   2340  
2338   If @ref is_bool() is `true`, returns a reference to **(1)** or a copy 2341   If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
2339   of **(2)** the underlying `bool`, otherwise throws an exception. 2342   of **(2)** the underlying `bool`, otherwise throws an exception.
2340   2343  
2341   @par Exception Safety 2344   @par Exception Safety
2342   Strong guarantee. 2345   Strong guarantee.
2343   2346  
2344   @throw boost::system::system_error `! this->is_bool()`. 2347   @throw boost::system::system_error `! this->is_bool()`.
2345   2348  
2346   @param loc @ref boost::source_location to use in thrown exception; the 2349   @param loc @ref boost::source_location to use in thrown exception; the
2347   source location of the call site by default. 2350   source location of the call site by default.
2348   2351  
2349   @par Complexity 2352   @par Complexity
2350   Constant. 2353   Constant.
2351   2354  
2352   @{ 2355   @{
2353   */ 2356   */
2354   BOOST_JSON_DECL 2357   BOOST_JSON_DECL
2355   bool& 2358   bool&
2356   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION); 2359   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
2357   2360  
2358   /// Overload 2361   /// Overload
2359   BOOST_JSON_DECL 2362   BOOST_JSON_DECL
2360   bool 2363   bool
2361   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2364   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2362   /// @} 2365   /// @}
2363   2366  
2364   //------------------------------------------------------ 2367   //------------------------------------------------------
2365   2368  
2366   /** Return the underlying @ref object, without checking. 2369   /** Return the underlying @ref object, without checking.
2367   2370  
2368   This is the fastest way to access the underlying representation when 2371   This is the fastest way to access the underlying representation when
2369   the kind is known in advance. 2372   the kind is known in advance.
2370   2373  
2371   @par Preconditions 2374   @par Preconditions
2372   2375  
2373   @code 2376   @code
2374   this->is_object() 2377   this->is_object()
2375   @endcode 2378   @endcode
2376   2379  
2377   @par Complexity 2380   @par Complexity
2378   Constant. 2381   Constant.
2379   2382  
2380   @par Exception Safety 2383   @par Exception Safety
2381   No-throw guarantee. 2384   No-throw guarantee.
2382   2385  
2383   @{ 2386   @{
2384   */ 2387   */
2385   object& 2388   object&
HITCBC 2386   40 get_object() & noexcept 2389   40 get_object() & noexcept
2387   { 2390   {
HITCBC 2388   40 BOOST_ASSERT(is_object()); 2391   40 BOOST_ASSERT(is_object());
HITCBC 2389   40 return obj_; 2392   40 return obj_;
2390   } 2393   }
2391   2394  
2392   object&& 2395   object&&
HITCBC 2393   1 get_object() && noexcept 2396   1 get_object() && noexcept
2394   { 2397   {
HITCBC 2395   1 BOOST_ASSERT(is_object()); 2398   1 BOOST_ASSERT(is_object());
HITCBC 2396   1 return std::move(obj_); 2399   1 return std::move(obj_);
2397   } 2400   }
2398   2401  
2399   object const& 2402   object const&
HITCBC 2400   52947 get_object() const& noexcept 2403   52947 get_object() const& noexcept
2401   { 2404   {
HITCBC 2402   52947 BOOST_ASSERT(is_object()); 2405   52947 BOOST_ASSERT(is_object());
HITCBC 2403   52947 return obj_; 2406   52947 return obj_;
2404   } 2407   }
2405   /// @} 2408   /// @}
2406   2409  
2407   /** Return the underlying @ref array, without checking. 2410   /** Return the underlying @ref array, without checking.
2408   2411  
2409   This is the fastest way to access the underlying representation when 2412   This is the fastest way to access the underlying representation when
2410   the kind is known in advance. 2413   the kind is known in advance.
2411   2414  
2412   @par Preconditions 2415   @par Preconditions
2413   2416  
2414   @code 2417   @code
2415   this->is_array() 2418   this->is_array()
2416   @endcode 2419   @endcode
2417   2420  
2418   @par Complexity 2421   @par Complexity
2419   Constant. 2422   Constant.
2420   2423  
2421   @par Exception Safety 2424   @par Exception Safety
2422   No-throw guarantee. 2425   No-throw guarantee.
2423   2426  
2424   @{ 2427   @{
2425   */ 2428   */
2426   array& 2429   array&
HITCBC 2427   27 get_array() & noexcept 2430   27 get_array() & noexcept
2428   { 2431   {
HITCBC 2429   27 BOOST_ASSERT(is_array()); 2432   27 BOOST_ASSERT(is_array());
HITCBC 2430   27 return arr_; 2433   27 return arr_;
2431   } 2434   }
2432   2435  
2433   array&& 2436   array&&
HITCBC 2434   1 get_array() && noexcept 2437   1 get_array() && noexcept
2435   { 2438   {
HITCBC 2436   1 BOOST_ASSERT(is_array()); 2439   1 BOOST_ASSERT(is_array());
HITCBC 2437   1 return std::move(arr_); 2440   1 return std::move(arr_);
2438   } 2441   }
2439   2442  
2440   array const& 2443   array const&
HITCBC 2441   5702 get_array() const& noexcept 2444   5702 get_array() const& noexcept
2442   { 2445   {
HITCBC 2443   5702 BOOST_ASSERT(is_array()); 2446   5702 BOOST_ASSERT(is_array());
HITCBC 2444   5702 return arr_; 2447   5702 return arr_;
2445   } 2448   }
2446   /// @} 2449   /// @}
2447   2450  
2448   /** Return the underlying @ref string, without checking. 2451   /** Return the underlying @ref string, without checking.
2449   2452  
2450   This is the fastest way to access the underlying representation when 2453   This is the fastest way to access the underlying representation when
2451   the kind is known in advance. 2454   the kind is known in advance.
2452   2455  
2453   @par Preconditions 2456   @par Preconditions
2454   2457  
2455   @code 2458   @code
2456   this->is_string() 2459   this->is_string()
2457   @endcode 2460   @endcode
2458   2461  
2459   @par Complexity 2462   @par Complexity
2460   Constant. 2463   Constant.
2461   2464  
2462   @par Exception Safety 2465   @par Exception Safety
2463   No-throw guarantee. 2466   No-throw guarantee.
2464   2467  
2465   @{ 2468   @{
2466   */ 2469   */
2467   string& 2470   string&
HITCBC 2468   8973 get_string() & noexcept 2471   8973 get_string() & noexcept
2469   { 2472   {
HITCBC 2470   8973 BOOST_ASSERT(is_string()); 2473   8973 BOOST_ASSERT(is_string());
HITCBC 2471   8973 return str_; 2474   8973 return str_;
2472   } 2475   }
2473   2476  
2474   string&& 2477   string&&
HITCBC 2475   1 get_string() && noexcept 2478   1 get_string() && noexcept
2476   { 2479   {
HITCBC 2477   1 BOOST_ASSERT(is_string()); 2480   1 BOOST_ASSERT(is_string());
HITCBC 2478   1 return std::move(str_); 2481   1 return std::move(str_);
2479   } 2482   }
2480   2483  
2481   string const& 2484   string const&
HITCBC 2482   40936 get_string() const& noexcept 2485   40936 get_string() const& noexcept
2483   { 2486   {
HITCBC 2484   40936 BOOST_ASSERT(is_string()); 2487   40936 BOOST_ASSERT(is_string());
HITCBC 2485   40936 return str_; 2488   40936 return str_;
2486   } 2489   }
2487   /// @} 2490   /// @}
2488   2491  
2489   /** Return the underlying `std::int64_t`, without checking. 2492   /** Return the underlying `std::int64_t`, without checking.
2490   2493  
2491   This is the fastest way to access the underlying representation when 2494   This is the fastest way to access the underlying representation when
2492   the kind is known in advance. 2495   the kind is known in advance.
2493   2496  
2494   @par Preconditions 2497   @par Preconditions
2495   2498  
2496   @code 2499   @code
2497   this->is_int64() 2500   this->is_int64()
2498   @endcode 2501   @endcode
2499   2502  
2500   @par Complexity 2503   @par Complexity
2501   Constant. 2504   Constant.
2502   2505  
2503   @par Exception Safety 2506   @par Exception Safety
2504   No-throw guarantee. 2507   No-throw guarantee.
2505   2508  
2506   @{ 2509   @{
2507   */ 2510   */
2508   std::int64_t& 2511   std::int64_t&
HITCBC 2509   3 get_int64() noexcept 2512   3 get_int64() noexcept
2510   { 2513   {
HITCBC 2511   3 BOOST_ASSERT(is_int64()); 2514   3 BOOST_ASSERT(is_int64());
HITCBC 2512   3 return sca_.i; 2515   3 return sca_.i;
2513   } 2516   }
2514   2517  
2515   std::int64_t 2518   std::int64_t
HITCBC 2516   14227 get_int64() const noexcept 2519   14227 get_int64() const noexcept
2517   { 2520   {
HITCBC 2518   14227 BOOST_ASSERT(is_int64()); 2521   14227 BOOST_ASSERT(is_int64());
HITCBC 2519   14227 return sca_.i; 2522   14227 return sca_.i;
2520   } 2523   }
2521   /// @} 2524   /// @}
2522   2525  
2523   /** Return the underlying `std::uint64_t`, without checking. 2526   /** Return the underlying `std::uint64_t`, without checking.
2524   2527  
2525   This is the fastest way to access the underlying representation when 2528   This is the fastest way to access the underlying representation when
2526   the kind is known in advance. 2529   the kind is known in advance.
2527   2530  
2528   @par Preconditions 2531   @par Preconditions
2529   2532  
2530   @code 2533   @code
2531   this->is_uint64() 2534   this->is_uint64()
2532   @endcode 2535   @endcode
2533   2536  
2534   @par Complexity 2537   @par Complexity
2535   Constant. 2538   Constant.
2536   2539  
2537   @par Exception Safety 2540   @par Exception Safety
2538   No-throw guarantee. 2541   No-throw guarantee.
2539   2542  
2540   @{ 2543   @{
2541   */ 2544   */
2542   std::uint64_t& 2545   std::uint64_t&
HITCBC 2543   3 get_uint64() noexcept 2546   3 get_uint64() noexcept
2544   { 2547   {
HITCBC 2545   3 BOOST_ASSERT(is_uint64()); 2548   3 BOOST_ASSERT(is_uint64());
HITCBC 2546   3 return sca_.u; 2549   3 return sca_.u;
2547   } 2550   }
2548   2551  
2549   std::uint64_t 2552   std::uint64_t
HITCBC 2550   195 get_uint64() const noexcept 2553   195 get_uint64() const noexcept
2551   { 2554   {
HITCBC 2552   195 BOOST_ASSERT(is_uint64()); 2555   195 BOOST_ASSERT(is_uint64());
HITCBC 2553   195 return sca_.u; 2556   195 return sca_.u;
2554   } 2557   }
2555   /// @} 2558   /// @}
2556   2559  
2557   /** Return the underlying `double`, without checking. 2560   /** Return the underlying `double`, without checking.
2558   2561  
2559   This is the fastest way to access the underlying 2562   This is the fastest way to access the underlying
2560   representation when the kind is known in advance. 2563   representation when the kind is known in advance.
2561   2564  
2562   @par Preconditions 2565   @par Preconditions
2563   2566  
2564   @code 2567   @code
2565   this->is_double() 2568   this->is_double()
2566   @endcode 2569   @endcode
2567   2570  
2568   @par Complexity 2571   @par Complexity
2569   Constant. 2572   Constant.
2570   2573  
2571   @par Exception Safety 2574   @par Exception Safety
2572   No-throw guarantee. 2575   No-throw guarantee.
2573   2576  
2574   @{ 2577   @{
2575   */ 2578   */
2576   double& 2579   double&
HITCBC 2577   3 get_double() noexcept 2580   3 get_double() noexcept
2578   { 2581   {
HITCBC 2579   3 BOOST_ASSERT(is_double()); 2582   3 BOOST_ASSERT(is_double());
HITCBC 2580   3 return sca_.d; 2583   3 return sca_.d;
2581   } 2584   }
2582   2585  
2583   double 2586   double
HITCBC 2584   39169 get_double() const noexcept 2587   39169 get_double() const noexcept
2585   { 2588   {
HITCBC 2586   39169 BOOST_ASSERT(is_double()); 2589   39169 BOOST_ASSERT(is_double());
HITCBC 2587   39169 return sca_.d; 2590   39169 return sca_.d;
2588   } 2591   }
2589   /// @} 2592   /// @}
2590   2593  
2591   /** Return the underlying `bool`, without checking. 2594   /** Return the underlying `bool`, without checking.
2592   2595  
2593   This is the fastest way to access the underlying representation when 2596   This is the fastest way to access the underlying representation when
2594   the kind is known in advance. 2597   the kind is known in advance.
2595   2598  
2596   @par Preconditions 2599   @par Preconditions
2597   2600  
2598   @code 2601   @code
2599   this->is_bool() 2602   this->is_bool()
2600   @endcode 2603   @endcode
2601   2604  
2602   @par Complexity 2605   @par Complexity
2603   Constant. 2606   Constant.
2604   2607  
2605   @par Exception Safety 2608   @par Exception Safety
2606   No-throw guarantee. 2609   No-throw guarantee.
2607   2610  
2608   @{ 2611   @{
2609   */ 2612   */
2610   bool& 2613   bool&
HITCBC 2611   3 get_bool() noexcept 2614   3 get_bool() noexcept
2612   { 2615   {
HITCBC 2613   3 BOOST_ASSERT(is_bool()); 2616   3 BOOST_ASSERT(is_bool());
HITCBC 2614   3 return sca_.b; 2617   3 return sca_.b;
2615   } 2618   }
2616   2619  
2617   bool 2620   bool
HITCBC 2618   777 get_bool() const noexcept 2621   777 get_bool() const noexcept
2619   { 2622   {
HITCBC 2620   777 BOOST_ASSERT(is_bool()); 2623   777 BOOST_ASSERT(is_bool());
HITCBC 2621   777 return sca_.b; 2624   777 return sca_.b;
2622   } 2625   }
2623   /// @} 2626   /// @}
2624   2627  
2625   //------------------------------------------------------ 2628   //------------------------------------------------------
2626   2629  
2627   /** Access an element, with bounds checking. 2630   /** Access an element, with bounds checking.
2628   2631  
2629   Returns `boost::system::result` containing a reference to the element 2632   Returns `boost::system::result` containing a reference to the element
2630   of the underlying ccontainer, if such element exists. If the underlying 2633   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 2634   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`. 2635   have a corresponding element the result contains an `error_code`.
2633   2636  
2634   , if `pos` is within its range. If `pos` is 2637   , if `pos` is within its range. If `pos` is
2635   outside of that range, or the underlying value is not an object the 2638   outside of that range, or the underlying value is not an object the
2636   2639  
2637   Returns @ref boost::system::result containing a reference to the 2640   Returns @ref boost::system::result containing a reference to the
2638   element of the underlying @ref array, if `pos` is within its range. If 2641   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 2642   `pos` is outside of that range, or the underlying value is not an array
2640   the result contains an `error_code`. 2643   the result contains an `error_code`.
2641   2644  
2642   This function is used to access elements of 2645   This function is used to access elements of
2643   the underlying container, or throw an exception if that could not be 2646   the underlying container, or throw an exception if that could not be
2644   done. 2647   done.
2645   2648  
2646   @li **(1)**, **(2)** require the underlying container to be an 2649   @li **(1)**, **(2)** require the underlying container to be an
2647   @ref object, and look for an element with the key `key`. 2650   @ref object, and look for an element with the key `key`.
2648   @li **(3)**, **(4)** require the underlying container to be an 2651   @li **(3)**, **(4)** require the underlying container to be an
2649   @ref array, and look for an element at index `pos`. 2652   @ref array, and look for an element at index `pos`.
2650   2653  
2651   @par Exception Safety 2654   @par Exception Safety
2652   No-throw guarantee. 2655   No-throw guarantee.
2653   2656  
2654   @param key The key of the element to find. 2657   @param key The key of the element to find.
2655   2658  
2656   @par Complexity 2659   @par Complexity
2657   Constant. 2660   Constant.
2658   2661  
2659   @par Exception Safety 2662   @par Exception Safety
2660   No-throw guarantee. 2663   No-throw guarantee.
2661   2664  
2662   @{ 2665   @{
2663   */ 2666   */
2664   BOOST_JSON_DECL 2667   BOOST_JSON_DECL
2665   boost::system::result<value&> 2668   boost::system::result<value&>
2666   try_at(string_view key) noexcept; 2669   try_at(string_view key) noexcept;
2667   2670  
2668   BOOST_JSON_DECL 2671   BOOST_JSON_DECL
2669   boost::system::result<value const&> 2672   boost::system::result<value const&>
2670   try_at(string_view key) const noexcept; 2673   try_at(string_view key) const noexcept;
2671   2674  
2672   /** Overload 2675   /** Overload
2673   2676  
2674   @param pos A zero-based array index. 2677   @param pos A zero-based array index.
2675   */ 2678   */
2676   BOOST_JSON_DECL 2679   BOOST_JSON_DECL
2677   boost::system::result<value&> 2680   boost::system::result<value&>
2678   try_at(std::size_t pos) noexcept; 2681   try_at(std::size_t pos) noexcept;
2679   2682  
2680   /// Overload 2683   /// Overload
2681   BOOST_JSON_DECL 2684   BOOST_JSON_DECL
2682   boost::system::result<value const&> 2685   boost::system::result<value const&>
2683   try_at(std::size_t pos) const noexcept; 2686   try_at(std::size_t pos) const noexcept;
2684   /// @} 2687   /// @}
2685   2688  
2686   2689  
2687   /** Access an element, with bounds checking. 2690   /** Access an element, with bounds checking.
2688   2691  
2689   This function is used to access elements of 2692   This function is used to access elements of
2690   the underlying container, or throw an exception if that could not be 2693   the underlying container, or throw an exception if that could not be
2691   done. 2694   done.
2692   2695  
2693   @li **(1)**--**(3)** is equivalent to 2696   @li **(1)**--**(3)** is equivalent to
2694   `this->as_object(loc).at(key, loc)`. 2697   `this->as_object(loc).at(key, loc)`.
2695   @li **(4)**--**(6)** is equivalent to 2698   @li **(4)**--**(6)** is equivalent to
2696   `this->as_array(loc).at(pos, loc)`. 2699   `this->as_array(loc).at(pos, loc)`.
2697   2700  
2698   @par Complexity 2701   @par Complexity
2699   Constant. 2702   Constant.
2700   2703  
2701   @par Exception Safety 2704   @par Exception Safety
2702   Strong guarantee. 2705   Strong guarantee.
2703   2706  
2704   @param key The key of the element to find. 2707   @param key The key of the element to find.
2705   @param loc @ref boost::source_location to use in thrown exception; the 2708   @param loc @ref boost::source_location to use in thrown exception; the
2706   source location of the call site by default. 2709   source location of the call site by default.
2707   2710  
2708   @throw boost::system::system_error The underlying type of value is not 2711   @throw boost::system::system_error The underlying type of value is not
2709   the container type corresponding to the first argument (i.e. 2712   the container type corresponding to the first argument (i.e.
2710   using an index with an @ref object). 2713   using an index with an @ref object).
2711   @throw boost::system::system_error An element corresponding to the 2714   @throw boost::system::system_error An element corresponding to the
2712   first argument was not found. 2715   first argument was not found.
2713   2716  
2714   @see @ref as_array, @ref as_object. 2717   @see @ref as_array, @ref as_object.
2715   2718  
2716   @{ 2719   @{
2717   */ 2720   */
2718   value& 2721   value&
HITCBC 2719   13 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) & 2722   13 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
2720   { 2723   {
HITCBC 2721   13 return as_object(loc).at(key, loc); 2724   13 return as_object(loc).at(key, loc);
2722   } 2725   }
2723   2726  
2724   /// Overload 2727   /// Overload
2725   value&& 2728   value&&
HITCBC 2726   1 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) && 2729   1 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2727   { 2730   {
HITCBC 2728   1 return std::move( as_object(loc) ).at(key, loc); 2731   1 return std::move( as_object(loc) ).at(key, loc);
2729   } 2732   }
2730   2733  
2731   /// Overload 2734   /// Overload
2732   value const& 2735   value const&
HITCBC 2733   18 at( 2736   18 at(
2734   string_view key, 2737   string_view key,
2735   source_location const& loc = BOOST_CURRENT_LOCATION) const& 2738   source_location const& loc = BOOST_CURRENT_LOCATION) const&
2736   { 2739   {
HITCBC 2737   18 return as_object(loc).at(key, loc); 2740   18 return as_object(loc).at(key, loc);
2738   } 2741   }
2739   2742  
2740   /** Overload 2743   /** Overload
2741   2744  
2742   @param pos A zero-based array index. 2745   @param pos A zero-based array index.
2743   @param loc 2746   @param loc
2744   */ 2747   */
2745   value & 2748   value &
HITCBC 2746   12 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) & 2749   12 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
2747   { 2750   {
HITCBC 2748   12 return as_array(loc).at(pos, loc); 2751   12 return as_array(loc).at(pos, loc);
2749   } 2752   }
2750   2753  
2751   /// Overload 2754   /// Overload
2752   value&& 2755   value&&
HITCBC 2753   10 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) && 2756   10 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2754   { 2757   {
HITCBC 2755   10 return std::move( as_array(loc) ).at(pos, loc); 2758   10 return std::move( as_array(loc) ).at(pos, loc);
2756   } 2759   }
2757   2760  
2758   /// Overload 2761   /// Overload
2759   value const& 2762   value const&
HITCBC 2760   56 at(std::size_t pos, 2763   56 at(std::size_t pos,
2761   source_location const& loc = BOOST_CURRENT_LOCATION) const& 2764   source_location const& loc = BOOST_CURRENT_LOCATION) const&
2762   { 2765   {
HITCBC 2763   56 return as_array(loc).at(pos, loc); 2766   56 return as_array(loc).at(pos, loc);
2764   } 2767   }
2765   /// @} 2768   /// @}
2766   2769  
2767   /** Access an element via JSON Pointer. 2770   /** Access an element via JSON Pointer.
2768   2771  
2769   This function is used to access a (potentially nested) element of the 2772   This function is used to access a (potentially nested) element of the
2770   value using a JSON Pointer string. 2773   value using a JSON Pointer string.
2771   2774  
2772   @par Complexity 2775   @par Complexity
2773   Linear in the sizes of `ptr` and underlying array, object, or string. 2776   Linear in the sizes of `ptr` and underlying array, object, or string.
2774   2777  
2775   @par Exception Safety 2778   @par Exception Safety
2776   No-throw guarantee. 2779   No-throw guarantee.
2777   2780  
2778   @param ptr JSON Pointer string. 2781   @param ptr JSON Pointer string.
2779   2782  
2780   @return @ref boost::system::result containing either a reference to the 2783   @return @ref boost::system::result containing either a reference to the
2781   element identified by `ptr` or a corresponding `error_code`. 2784   element identified by `ptr` or a corresponding `error_code`.
2782   2785  
2783   @see 2786   @see
2784   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2787   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2785   2788  
2786   @{ 2789   @{
2787   */ 2790   */
2788   BOOST_JSON_DECL 2791   BOOST_JSON_DECL
2789   system::result<value const&> 2792   system::result<value const&>
2790   try_at_pointer(string_view ptr) const noexcept; 2793   try_at_pointer(string_view ptr) const noexcept;
2791   2794  
2792   BOOST_JSON_DECL 2795   BOOST_JSON_DECL
2793   system::result<value&> 2796   system::result<value&>
2794   try_at_pointer(string_view ptr) noexcept; 2797   try_at_pointer(string_view ptr) noexcept;
2795   /// @} 2798   /// @}
2796   2799  
2797   /** Access an element via JSON Pointer. 2800   /** Access an element via JSON Pointer.
2798   2801  
2799   This function is used to access a (potentially nested) element of the 2802   This function is used to access a (potentially nested) element of the
2800   value using a JSON Pointer string. 2803   value using a JSON Pointer string.
2801   2804  
2802   @par Complexity 2805   @par Complexity
2803   Linear in the sizes of `ptr` and the underlying container. 2806   Linear in the sizes of `ptr` and the underlying container.
2804   2807  
2805   @par Exception Safety 2808   @par Exception Safety
2806   Strong guarantee. 2809   Strong guarantee.
2807   2810  
2808   @param ptr JSON Pointer string. 2811   @param ptr JSON Pointer string.
2809   @param loc @ref boost::source_location to use in thrown exception; the 2812   @param loc @ref boost::source_location to use in thrown exception; the
2810   source location of the call site by default. 2813   source location of the call site by default.
2811   2814  
2812   @return reference to the element identified by `ptr`. 2815   @return reference to the element identified by `ptr`.
2813   2816  
2814   @throw boost::system::system_error if an error occurs. 2817   @throw boost::system::system_error if an error occurs.
2815   2818  
2816   @see 2819   @see
2817   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2820   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2818   2821  
2819   @{ 2822   @{
2820   */ 2823   */
2821   BOOST_JSON_DECL 2824   BOOST_JSON_DECL
2822   value const& 2825   value const&
2823   at_pointer( 2826   at_pointer(
2824   string_view ptr, 2827   string_view ptr,
2825   source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2828   source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2826   2829  
2827   /// Overload 2830   /// Overload
2828   inline 2831   inline
2829   value&& 2832   value&&
2830   at_pointer( 2833   at_pointer(
2831   string_view ptr, 2834   string_view ptr,
2832   source_location const& loc = BOOST_CURRENT_LOCATION) &&; 2835   source_location const& loc = BOOST_CURRENT_LOCATION) &&;
2833   2836  
2834   /// Overload 2837   /// Overload
2835   inline 2838   inline
2836   value& 2839   value&
2837   at_pointer( 2840   at_pointer(
2838   string_view ptr, 2841   string_view ptr,
2839   source_location const& loc = BOOST_CURRENT_LOCATION) &; 2842   source_location const& loc = BOOST_CURRENT_LOCATION) &;
2840   /// @} 2843   /// @}
2841   2844  
2842   /** Access an element via JSON Pointer. 2845   /** Access an element via JSON Pointer.
2843   2846  
2844   This function is used to access a (potentially nested) element of the 2847   This function is used to access a (potentially nested) element of the
2845   value using a JSON Pointer string. 2848   value using a JSON Pointer string.
2846   2849  
2847   @par Complexity 2850   @par Complexity
2848   Linear in the sizes of `ptr` and underlying container. 2851   Linear in the sizes of `ptr` and underlying container.
2849   2852  
2850   @par Exception Safety 2853   @par Exception Safety
2851   No-throw guarantee. 2854   No-throw guarantee.
2852   2855  
2853   @param ptr JSON Pointer string. 2856   @param ptr JSON Pointer string.
2854   @param ec Set to the error, if any occurred. 2857   @param ec Set to the error, if any occurred.
2855   2858  
2856   @return pointer to the element identified by `ptr`. 2859   @return pointer to the element identified by `ptr`.
2857   2860  
2858   @see 2861   @see
2859   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901) 2862   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
2860   2863  
2861   @{ 2864   @{
2862   */ 2865   */
2863   BOOST_JSON_DECL 2866   BOOST_JSON_DECL
2864   value const* 2867   value const*
2865   find_pointer(string_view ptr, system::error_code& ec) const noexcept; 2868   find_pointer(string_view ptr, system::error_code& ec) const noexcept;
2866   2869  
2867   BOOST_JSON_DECL 2870   BOOST_JSON_DECL
2868   value* 2871   value*
2869   find_pointer(string_view ptr, system::error_code& ec) noexcept; 2872   find_pointer(string_view ptr, system::error_code& ec) noexcept;
2870   2873  
2871   BOOST_JSON_DECL 2874   BOOST_JSON_DECL
2872   value const* 2875   value const*
2873   find_pointer(string_view ptr, std::error_code& ec) const noexcept; 2876   find_pointer(string_view ptr, std::error_code& ec) const noexcept;
2874   2877  
2875   BOOST_JSON_DECL 2878   BOOST_JSON_DECL
2876   value* 2879   value*
2877   find_pointer(string_view ptr, std::error_code& ec) noexcept; 2880   find_pointer(string_view ptr, std::error_code& ec) noexcept;
2878   /// @} 2881   /// @}
2879   2882  
2880   //------------------------------------------------------ 2883   //------------------------------------------------------
2881   2884  
2882   /** Set an element via JSON Pointer. 2885   /** Set an element via JSON Pointer.
2883   2886  
2884   This function is used to insert or assign to a potentially nested 2887   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 2888   element of the value using a JSON Pointer string. The function may
2886   create intermediate elements corresponding to pointer segments. 2889   create intermediate elements corresponding to pointer segments.
2887   2890  
2888   The particular conditions when and what kind of intermediate element 2891   The particular conditions when and what kind of intermediate element
2889   is created is governed by the `ptr` parameter. 2892   is created is governed by the `ptr` parameter.
2890   2893  
2891   Each pointer token is considered in sequence. For each token 2894   Each pointer token is considered in sequence. For each token
2892   2895  
2893   - if the containing value is an @ref object, then a new `null` 2896   - if the containing value is an @ref object, then a new `null`
2894   element is created with key equal to unescaped token string; 2897   element is created with key equal to unescaped token string;
2895   otherwise 2898   otherwise
2896   2899  
2897   - 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
2898   past-the-end marker, then a `null` element is appended to the array; 2901   past-the-end marker, then a `null` element is appended to the array;
2899   otherwise 2902   otherwise
2900   2903  
2901   - if the containing value is an @ref array, and the token represents a 2904   - 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 2905   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 2906   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 2907   array is increased, so that the number can reference an element in the
2905   array; otherwise 2908   array; otherwise
2906   2909  
2907   - if the containing value is of different @ref kind and 2910   - if the containing value is of different @ref kind and
2908   `opts.replace_any_scalar` is `true`, or the value is `null`, then 2911   `opts.replace_any_scalar` is `true`, or the value is `null`, then
2909   2912  
2910   - if `opts.create_arrays` is `true` and the token either represents 2913   - 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 2914   past-the-end marker or a number, then the value is replaced with
2912   an empty array and the token is considered again; otherwise 2915   an empty array and the token is considered again; otherwise
2913   2916  
2914   - if `opts.create_objects` is `true`, then the value is replaced 2917   - if `opts.create_objects` is `true`, then the value is replaced
2915   with an empty object and the token is considered again; otherwise 2918   with an empty object and the token is considered again; otherwise
2916   2919  
2917   - an error is produced. 2920   - an error is produced.
2918   2921  
2919   @par Complexity 2922   @par Complexity
2920   Linear in the sum of size of `ptr`, size of underlying array, object, 2923   Linear in the sum of size of `ptr`, size of underlying array, object,
2921   or string and `opts.max_created_elements`. 2924   or string and `opts.max_created_elements`.
2922   2925  
2923   @par Exception Safety 2926   @par Exception Safety
2924   Basic guarantee. Calls to `memory_resource::allocate` may throw. 2927   Basic guarantee. Calls to `memory_resource::allocate` may throw.
2925   2928  
2926   @param sv JSON Pointer string. 2929   @param sv JSON Pointer string.
2927   @param ref The value to assign to pointed element. 2930   @param ref The value to assign to pointed element.
2928   @param opts The options for the algorithm. 2931   @param opts The options for the algorithm.
2929   2932  
2930   @return @ref boost::system::result containing either a reference to the 2933   @return @ref boost::system::result containing either a reference to the
2931   element identified by `ptr` or a corresponding `error_code`. 2934   element identified by `ptr` or a corresponding `error_code`.
2932   2935  
2933   @see 2936   @see
2934   @ref set_pointer_options, 2937   @ref set_pointer_options,
2935   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2938   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2936   */ 2939   */
2937   BOOST_JSON_DECL 2940   BOOST_JSON_DECL
2938   system::result<value&> 2941   system::result<value&>
2939   try_set_at_pointer( 2942   try_set_at_pointer(
2940   string_view sv, 2943   string_view sv,
2941   value_ref ref, 2944   value_ref ref,
2942   set_pointer_options const& opts = {} ); 2945   set_pointer_options const& opts = {} );
2943   2946  
2944   /** Set an element via JSON Pointer. 2947   /** Set an element via JSON Pointer.
2945   2948  
2946   This function is used to insert or assign to a potentially nested 2949   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 2950   element of the value using a JSON Pointer string. The function may
2948   create intermediate elements corresponding to pointer segments. 2951   create intermediate elements corresponding to pointer segments.
2949   2952  
2950   The particular conditions when and what kind of intermediate element 2953   The particular conditions when and what kind of intermediate element
2951   is created is governed by the `ptr` parameter. 2954   is created is governed by the `ptr` parameter.
2952   2955  
2953   Each pointer token is considered in sequence. For each token 2956   Each pointer token is considered in sequence. For each token
2954   2957  
2955   - if the containing value is an @ref object, then a new `null` 2958   - if the containing value is an @ref object, then a new `null`
2956   element is created with key equal to unescaped token string; otherwise 2959   element is created with key equal to unescaped token string; otherwise
2957   2960  
2958   - 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
2959   past-the-end marker, then a `null` element is appended to the array; 2962   past-the-end marker, then a `null` element is appended to the array;
2960   otherwise 2963   otherwise
2961   2964  
2962   - if the containing value is an @ref array, and the token represents a 2965   - 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 2966   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 2967   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 2968   array is increased, so that the number can reference an element in the
2966   array; otherwise 2969   array; otherwise
2967   2970  
2968   - if the containing value is of different @ref kind and 2971   - if the containing value is of different @ref kind and
2969   `opts.replace_any_scalar` is `true`, or the value is `null`, then 2972   `opts.replace_any_scalar` is `true`, or the value is `null`, then
2970   2973  
2971   - if `opts.create_arrays` is `true` and the token either represents 2974   - 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 2975   past-the-end marker or a number, then the value is replaced with
2973   an empty array and the token is considered again; otherwise 2976   an empty array and the token is considered again; otherwise
2974   2977  
2975   - if `opts.create_objects` is `true`, then the value is replaced 2978   - if `opts.create_objects` is `true`, then the value is replaced
2976   with an empty object and the token is considered again; otherwise 2979   with an empty object and the token is considered again; otherwise
2977   2980  
2978   - an error is produced. 2981   - an error is produced.
2979   2982  
2980   @par Complexity 2983   @par Complexity
2981   Linear in the sum of size of `ptr`, size of underlying array, object, 2984   Linear in the sum of size of `ptr`, size of underlying array, object,
2982   or string and `opts.max_created_elements`. 2985   or string and `opts.max_created_elements`.
2983   2986  
2984   @par Exception Safety 2987   @par Exception Safety
2985   Basic guarantee. 2988   Basic guarantee.
2986   Calls to `memory_resource::allocate` may throw. 2989   Calls to `memory_resource::allocate` may throw.
2987   2990  
2988   @param sv JSON Pointer string. 2991   @param sv JSON Pointer string.
2989   2992  
2990   @param ref The value to assign to pointed element. 2993   @param ref The value to assign to pointed element.
2991   2994  
2992   @param opts The options for the algorithm. 2995   @param opts The options for the algorithm.
2993   2996  
  2997 + @param loc @ref boost::source_location to use in thrown exception; the
  2998 + source location of the call site by default.
  2999 +
2994   @return Reference to the element identified by `ptr`. 3000   @return Reference to the element identified by `ptr`.
2995   3001  
2996   @throws boost::system::system_error Overload **(1)** reports errors by 3002   @throws boost::system::system_error Overload **(1)** reports errors by
2997   throwing exceptions. 3003   throwing exceptions.
2998   3004  
2999   @see @ref set_pointer_options, 3005   @see @ref set_pointer_options,
3000   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">). 3006   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
3001   3007  
3002   @{ 3008   @{
3003   */ 3009   */
3004   BOOST_JSON_DECL 3010   BOOST_JSON_DECL
3005   value& 3011   value&
3006   set_at_pointer( 3012   set_at_pointer(
3007   string_view sv, 3013   string_view sv,
3008   value_ref ref, 3014   value_ref ref,
3009 - set_pointer_options const& opts = {} ); 3015 + set_pointer_options const& opts = {},
  3016 + source_location const& loc = BOOST_CURRENT_LOCATION);
3010   3017  
3011   /** Overload 3018   /** Overload
3012   3019  
3013   @param ec Set to the error, if any occurred. 3020   @param ec Set to the error, if any occurred.
3014   @param sv 3021   @param sv
3015   @param ref 3022   @param ref
3016   @param opts 3023   @param opts
3017   */ 3024   */
3018   BOOST_JSON_DECL 3025   BOOST_JSON_DECL
3019   value* 3026   value*
3020   set_at_pointer( 3027   set_at_pointer(
3021   string_view sv, 3028   string_view sv,
3022   value_ref ref, 3029   value_ref ref,
3023   system::error_code& ec, 3030   system::error_code& ec,
3024   set_pointer_options const& opts = {} ); 3031   set_pointer_options const& opts = {} );
3025   3032  
3026   /// Overload 3033   /// Overload
3027   BOOST_JSON_DECL 3034   BOOST_JSON_DECL
3028   value* 3035   value*
3029   set_at_pointer( 3036   set_at_pointer(
3030   string_view sv, 3037   string_view sv,
3031   value_ref ref, 3038   value_ref ref,
3032   std::error_code& ec, 3039   std::error_code& ec,
3033   set_pointer_options const& opts = {} ); 3040   set_pointer_options const& opts = {} );
3034   /// @} 3041   /// @}
3035   3042  
3036   //------------------------------------------------------ 3043   //------------------------------------------------------
3037   3044  
3038   /** Check if two values are equal. 3045   /** Check if two values are equal.
3039   3046  
3040   Two values are equal when they are the same kind and their referenced 3047   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 3048   values are equal, or when they are both integral types and their
3042   integral representations are equal. 3049   integral representations are equal.
3043   3050  
3044   @par Complexity 3051   @par Complexity
3045   Constant or linear in the size of the underlying @ref array, @ref object, 3052   Constant or linear in the size of the underlying @ref array, @ref object,
3046   or @ref string. 3053   or @ref string.
3047   3054  
3048   @par Exception Safety 3055   @par Exception Safety
3049   No-throw guarantee. 3056   No-throw guarantee.
3050   */ 3057   */
3051   // inline friend speeds up overload resolution 3058   // inline friend speeds up overload resolution
3052   friend 3059   friend
3053   bool 3060   bool
HITCBC 3054   4172 operator==( 3061   4172 operator==(
3055   value const& lhs, 3062   value const& lhs,
3056   value const& rhs) noexcept 3063   value const& rhs) noexcept
3057   { 3064   {
HITCBC 3058   4172 return lhs.equal(rhs); 3065   4172 return lhs.equal(rhs);
3059   } 3066   }
3060   3067  
3061   /** Check if two values are not equal. 3068   /** Check if two values are not equal.
3062   3069  
3063   Two values are equal when they are the same kind and their referenced 3070   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 3071   values are equal, or when they are both integral types and their
3065   integral representations are equal. 3072   integral representations are equal.
3066   3073  
3067   @par Complexity 3074   @par Complexity
3068   Constant or linear in the size of the underlying @ref array, 3075   Constant or linear in the size of the underlying @ref array,
3069   @ref object, or @ref string. 3076   @ref object, or @ref string.
3070   3077  
3071   @par Exception Safety 3078   @par Exception Safety
3072   No-throw guarantee. 3079   No-throw guarantee.
3073   */ 3080   */
3074   friend 3081   friend
3075   bool 3082   bool
HITCBC 3076   3989 operator!=( 3083   3989 operator!=(
3077   value const& lhs, 3084   value const& lhs,
3078   value const& rhs) noexcept 3085   value const& rhs) noexcept
3079   { 3086   {
HITCBC 3080   3989 return ! (lhs == rhs); 3087   3989 return ! (lhs == rhs);
3081   } 3088   }
3082   3089  
3083   /** Serialize @ref value to an output stream. 3090   /** Serialize @ref value to an output stream.
3084   3091  
3085   This function serializes a `value` as JSON text into the output stream. 3092   This function serializes a `value` as JSON text into the output stream.
3086   3093  
3087   @return Reference to `os`. 3094   @return Reference to `os`.
3088   3095  
3089   @par Complexity 3096   @par Complexity
3090   Constant or linear in the size of `jv`. 3097   Constant or linear in the size of `jv`.
3091   3098  
3092   @par Exception Safety 3099   @par Exception Safety
3093   Strong guarantee. 3100   Strong guarantee.
3094   Calls to `memory_resource::allocate` may throw. 3101   Calls to `memory_resource::allocate` may throw.
3095   3102  
3096   @param os The output stream to serialize to. 3103   @param os The output stream to serialize to.
3097   3104  
3098   @param jv The value to serialize. 3105   @param jv The value to serialize.
3099   */ 3106   */
3100   BOOST_JSON_DECL 3107   BOOST_JSON_DECL
3101   friend 3108   friend
3102   std::ostream& 3109   std::ostream&
3103   operator<<( 3110   operator<<(
3104   std::ostream& os, 3111   std::ostream& os,
3105   value const& jv); 3112   value const& jv);
3106   3113  
3107   /** Parse @ref value from an input stream. 3114   /** Parse @ref value from an input stream.
3108   3115  
3109   This function parses JSON from an input stream into a `value`. If 3116   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 3117   parsing fails, @ref std::ios_base::failbit will be set for `is` and
3111   `jv` will be left unchanged. Regardless of whether @ref 3118   `jv` will be left unchanged. Regardless of whether @ref
3112   std::ios_base::skipws flag is set on `is`, consumes whitespace before 3119   std::ios_base::skipws flag is set on `is`, consumes whitespace before
3113   and after JSON, because whitespace is considered a part of JSON. 3120   and after JSON, because whitespace is considered a part of JSON.
3114   Behaves as 3121   Behaves as
3115   [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction). 3122   [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
3116   3123  
3117   @note This operator cannot assume that the stream only contains a 3124   @note This operator cannot assume that the stream only contains a
3118   single JSON document, which may result in **very underwhelming 3125   single JSON document, which may result in **very underwhelming
3119   performance**, if the stream isn't cooperative. If you know that your 3126   performance**, if the stream isn't cooperative. If you know that your
3120   input consists of a single JSON document, consider using @ref parse 3127   input consists of a single JSON document, consider using @ref parse
3121   function instead. 3128   function instead.
3122   3129  
3123   @return Reference to `is`. 3130   @return Reference to `is`.
3124   3131  
3125   @par Complexity 3132   @par Complexity
3126   Linear in the size of JSON data. 3133   Linear in the size of JSON data.
3127   3134  
3128   @par Exception Safety 3135   @par Exception Safety
3129   Basic guarantee. 3136   Basic guarantee.
3130   Calls to `memory_resource::allocate` may throw. 3137   Calls to `memory_resource::allocate` may throw.
3131   The stream may throw as configured by @ref std::ios::exceptions. 3138   The stream may throw as configured by @ref std::ios::exceptions.
3132   3139  
3133   @param is The input stream to parse from. 3140   @param is The input stream to parse from.
3134   3141  
3135   @param jv The value to parse into. 3142   @param jv The value to parse into.
3136   3143  
3137   @see @ref parse. 3144   @see @ref parse.
3138   */ 3145   */
3139   BOOST_JSON_DECL 3146   BOOST_JSON_DECL
3140   friend 3147   friend
3141   std::istream& 3148   std::istream&
3142   operator>>( 3149   operator>>(
3143   std::istream& is, 3150   std::istream& is,
3144   value& jv); 3151   value& jv);
3145   3152  
3146   /** Helper for @ref boost::hash support. 3153   /** Helper for @ref boost::hash support.
3147   3154  
3148   Computes a hash value for `jv`. This function is used by 3155   Computes a hash value for `jv`. This function is used by
3149   `boost::hash<value>`. Similar overloads for @ref array, @ref object, 3156   `boost::hash<value>`. Similar overloads for @ref array, @ref object,
3150   and @ref string do not exist, because those types are supported by 3157   and @ref string do not exist, because those types are supported by
3151   `boost::hash` out of the box. 3158   `boost::hash` out of the box.
3152   3159  
3153   @return hash value for `jv`. 3160   @return hash value for `jv`.
3154   3161  
3155   @param jv `value` for which a hash is to be computed. 3162   @param jv `value` for which a hash is to be computed.
3156   3163  
3157   @see [Boost.ContainerHash](https://boost.org/libs/container_hash). 3164   @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
3158   */ 3165   */
3159   #ifndef BOOST_JSON_DOCS 3166   #ifndef BOOST_JSON_DOCS
3160   template< 3167   template<
3161   class T, 3168   class T,
3162   typename std::enable_if< 3169   typename std::enable_if<
3163   std::is_same< detail::remove_cvref<T>, value >::value >::type* 3170   std::is_same< detail::remove_cvref<T>, value >::value >::type*
3164   = nullptr> 3171   = nullptr>
3165   friend 3172   friend
3166   std::size_t 3173   std::size_t
HITCBC 3167   248 hash_value( T const& jv ) noexcept 3174   248 hash_value( T const& jv ) noexcept
3168   #else 3175   #else
3169   friend 3176   friend
3170   inline 3177   inline
3171   std::size_t 3178   std::size_t
3172   hash_value( value const& jv ) noexcept 3179   hash_value( value const& jv ) noexcept
3173   #endif 3180   #endif
3174   { 3181   {
HITCBC 3175   248 return detail::hash_value_impl(jv); 3182   248 return detail::hash_value_impl(jv);
3176   } 3183   }
3177   3184  
3178   private: 3185   private:
3179   static 3186   static
3180   void 3187   void
HITCBC 3181   2133719 relocate( 3188   2133719 relocate(
3182   value* dest, 3189   value* dest,
3183   value const& src) noexcept 3190   value const& src) noexcept
3184   { 3191   {
HITCBC 3185   2133719 std::memcpy( 3192   2133719 std::memcpy(
3186   static_cast<void*>(dest), 3193   static_cast<void*>(dest),
3187   &src, 3194   &src,
3188   sizeof(src)); 3195   sizeof(src));
HITCBC 3189   2133719 } 3196   2133719 }
3190   3197  
3191   BOOST_JSON_DECL 3198   BOOST_JSON_DECL
3192   storage_ptr 3199   storage_ptr
3193   destroy() noexcept; 3200   destroy() noexcept;
3194   3201  
3195   BOOST_JSON_DECL 3202   BOOST_JSON_DECL
3196   bool 3203   bool
3197   equal(value const& other) const noexcept; 3204   equal(value const& other) const noexcept;
3198   3205  
3199   template<class T> 3206   template<class T>
3200   auto 3207   auto
HITCBC 3201   3408 to_number(error& e) const noexcept -> 3208   3408 to_number(error& e) const noexcept ->
3202   typename std::enable_if< 3209   typename std::enable_if<
3203   std::is_signed<T>::value && 3210   std::is_signed<T>::value &&
3204   ! std::is_floating_point<T>::value, 3211   ! std::is_floating_point<T>::value,
3205   T>::type 3212   T>::type
3206   { 3213   {
HITCBC 3207   3408 if(sca_.k == json::kind::int64) 3214   3408 if(sca_.k == json::kind::int64)
3208   { 3215   {
HITCBC 3209   3321 auto const i = sca_.i; 3216   3321 auto const i = sca_.i;
HITCBC 3210   6636 if( i >= (std::numeric_limits<T>::min)() && 3217   6636 if( i >= (std::numeric_limits<T>::min)() &&
HITCBC 3211   3315 i <= (std::numeric_limits<T>::max)()) 3218   3315 i <= (std::numeric_limits<T>::max)())
3212   { 3219   {
HITCBC 3213   3309 e = {}; 3220   3309 e = {};
HITCBC 3214   3309 return static_cast<T>(i); 3221   3309 return static_cast<T>(i);
3215   } 3222   }
HITCBC 3216   12 e = error::not_exact; 3223   12 e = error::not_exact;
3217   } 3224   }
HITCBC 3218   87 else if(sca_.k == json::kind::uint64) 3225   87 else if(sca_.k == json::kind::uint64)
3219   { 3226   {
HITCBC 3220   20 auto const u = sca_.u; 3227   20 auto const u = sca_.u;
HITCBC 3221   20 if(u <= static_cast<std::uint64_t>(( 3228   20 if(u <= static_cast<std::uint64_t>((
HITCBC 3222   20 std::numeric_limits<T>::max)())) 3229   20 std::numeric_limits<T>::max)()))
3223   { 3230   {
HITCBC 3224   10 e = {}; 3231   10 e = {};
HITCBC 3225   10 return static_cast<T>(u); 3232   10 return static_cast<T>(u);
3226   } 3233   }
HITCBC 3227   10 e = error::not_exact; 3234   10 e = error::not_exact;
3228   } 3235   }
HITCBC 3229   67 else if(sca_.k == json::kind::double_) 3236   67 else if(sca_.k == json::kind::double_)
3230   { 3237   {
HITCBC 3231   20 auto const d = sca_.d; 3238   20 auto const d = sca_.d;
HITCBC 3232   20 if( d >= static_cast<double>( 3239   20 if( d >= static_cast<double>(
HITCBC 3233   40 (detail::to_number_limit<T>::min)()) && 3240   40 (detail::to_number_limit<T>::min)()) &&
3234   d <= static_cast<double>( 3241   d <= static_cast<double>(
HITCBC 3235   40 (detail::to_number_limit<T>::max)()) && 3242   40 (detail::to_number_limit<T>::max)()) &&
HITCBC 3236   20 static_cast<T>(d) == d) 3243   20 static_cast<T>(d) == d)
3237   { 3244   {
HITCBC 3238   9 e = {}; 3245   9 e = {};
HITCBC 3239   9 return static_cast<T>(d); 3246   9 return static_cast<T>(d);
3240   } 3247   }
HITCBC 3241   11 e = error::not_exact; 3248   11 e = error::not_exact;
3242   } 3249   }
3243   else 3250   else
3244   { 3251   {
HITCBC 3245   47 e = error::not_number; 3252   47 e = error::not_number;
3246   } 3253   }
HITCBC 3247   80 return T{}; 3254   80 return T{};
3248   } 3255   }
3249   3256  
3250   template<class T> 3257   template<class T>
3251   auto 3258   auto
HITCBC 3252   119 to_number(error& e) const noexcept -> 3259   119 to_number(error& e) const noexcept ->
3253   typename std::enable_if< 3260   typename std::enable_if<
3254   std::is_unsigned<T>::value && 3261   std::is_unsigned<T>::value &&
3255   ! std::is_same<T, bool>::value, 3262   ! std::is_same<T, bool>::value,
3256   T>::type 3263   T>::type
3257   { 3264   {
HITCBC 3258   119 if(sca_.k == json::kind::int64) 3265   119 if(sca_.k == json::kind::int64)
3259   { 3266   {
HITCBC 3260   44 auto const i = sca_.i; 3267   44 auto const i = sca_.i;
HITCBC 3261   72 if( i >= 0 && static_cast<std::uint64_t>(i) <= 3268   72 if( i >= 0 && static_cast<std::uint64_t>(i) <=
HITCBC 3262   28 (std::numeric_limits<T>::max)()) 3269   28 (std::numeric_limits<T>::max)())
3263   { 3270   {
HITCBC 3264   22 e = {}; 3271   22 e = {};
HITCBC 3265   22 return static_cast<T>(i); 3272   22 return static_cast<T>(i);
3266   } 3273   }
HITCBC 3267   22 e = error::not_exact; 3274   22 e = error::not_exact;
3268   } 3275   }
HITCBC 3269   75 else if(sca_.k == json::kind::uint64) 3276   75 else if(sca_.k == json::kind::uint64)
3270   { 3277   {
HITCBC 3271   58 auto const u = sca_.u; 3278   58 auto const u = sca_.u;
HITCBC 3272   58 if(u <= (std::numeric_limits<T>::max)()) 3279   58 if(u <= (std::numeric_limits<T>::max)())
3273   { 3280   {
HITCBC 3274   52 e = {}; 3281   52 e = {};
HITCBC 3275   52 return static_cast<T>(u); 3282   52 return static_cast<T>(u);
3276   } 3283   }
HITCBC 3277   6 e = error::not_exact; 3284   6 e = error::not_exact;
3278   } 3285   }
HITCBC 3279   17 else if(sca_.k == json::kind::double_) 3286   17 else if(sca_.k == json::kind::double_)
3280   { 3287   {
HITCBC 3281   12 auto const d = sca_.d; 3288   12 auto const d = sca_.d;
HITCBC 3282   8 if( d >= 0 && 3289   8 if( d >= 0 &&
HITCBC 3283   20 d <= (detail::to_number_limit<T>::max)() && 3290   20 d <= (detail::to_number_limit<T>::max)() &&
HITCBC 3284   8 static_cast<T>(d) == d) 3291   8 static_cast<T>(d) == d)
3285   { 3292   {
HITCBC 3286   4 e = {}; 3293   4 e = {};
HITCBC 3287   4 return static_cast<T>(d); 3294   4 return static_cast<T>(d);
3288   } 3295   }
HITCBC 3289   8 e = error::not_exact; 3296   8 e = error::not_exact;
3290   } 3297   }
3291   else 3298   else
3292   { 3299   {
HITCBC 3293   5 e = error::not_number; 3300   5 e = error::not_number;
3294   } 3301   }
HITCBC 3295   41 return T{}; 3302   41 return T{};
3296   } 3303   }
3297   3304  
3298   template<class T> 3305   template<class T>
3299   auto 3306   auto
HITCBC 3300   67 to_number(error& e) const noexcept -> 3307   67 to_number(error& e) const noexcept ->
3301   typename std::enable_if< 3308   typename std::enable_if<
3302   std::is_floating_point< 3309   std::is_floating_point<
3303   T>::value, T>::type 3310   T>::value, T>::type
3304   { 3311   {
HITCBC 3305   67 if(sca_.k == json::kind::int64) 3312   67 if(sca_.k == json::kind::int64)
3306   { 3313   {
HITCBC 3307   16 e = {}; 3314   16 e = {};
HITCBC 3308   16 return static_cast<T>(sca_.i); 3315   16 return static_cast<T>(sca_.i);
3309   } 3316   }
HITCBC 3310   51 if(sca_.k == json::kind::uint64) 3317   51 if(sca_.k == json::kind::uint64)
3311   { 3318   {
HITCBC 3312   10 e = {}; 3319   10 e = {};
HITCBC 3313   10 return static_cast<T>(sca_.u); 3320   10 return static_cast<T>(sca_.u);
3314   } 3321   }
HITCBC 3315   41 if(sca_.k == json::kind::double_) 3322   41 if(sca_.k == json::kind::double_)
3316   { 3323   {
HITCBC 3317   27 e = {}; 3324   27 e = {};
HITCBC 3318   27 return static_cast<T>(sca_.d); 3325   27 return static_cast<T>(sca_.d);
3319   } 3326   }
HITCBC 3320   14 e = error::not_number; 3327   14 e = error::not_number;
HITCBC 3321   14 return {}; 3328   14 return {};
3322   } 3329   }
3323   }; 3330   };
3324   3331  
3325   // Make sure things are as big as we think they should be 3332   // Make sure things are as big as we think they should be
3326   #if BOOST_JSON_ARCH == 64 3333   #if BOOST_JSON_ARCH == 64
3327   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 ); 3334   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3328   #elif BOOST_JSON_ARCH == 32 3335   #elif BOOST_JSON_ARCH == 32
3329   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 ); 3336   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3330   #else 3337   #else
3331   # error Unknown architecture 3338   # error Unknown architecture
3332   #endif 3339   #endif
3333   3340  
3334   //---------------------------------------------------------- 3341   //----------------------------------------------------------
3335   3342  
3336   /** A key/value pair. 3343   /** A key/value pair.
3337   3344  
3338   This is the type of element used by the @ref object container. 3345   This is the type of element used by the @ref object container.
3339   */ 3346   */
3340   class key_value_pair 3347   class key_value_pair
3341   { 3348   {
3342   #ifndef BOOST_JSON_DOCS 3349   #ifndef BOOST_JSON_DOCS
3343   friend struct detail::access; 3350   friend struct detail::access;
3344   using access = detail::access; 3351   using access = detail::access;
3345   #endif 3352   #endif
3346   3353  
3347   BOOST_JSON_DECL 3354   BOOST_JSON_DECL
3348   static char const empty_[1]; 3355   static char const empty_[1];
3349   3356  
3350   inline 3357   inline
3351   key_value_pair( 3358   key_value_pair(
3352   pilfered<json::value> k, 3359   pilfered<json::value> k,
3353   pilfered<json::value> v) noexcept; 3360   pilfered<json::value> v) noexcept;
3354   3361  
3355   public: 3362   public:
3356   /** Assignment 3363   /** Assignment
3357   3364  
3358   This type is not copy or move-assignable. The copy assignment operator 3365   This type is not copy or move-assignable. The copy assignment operator
3359   is deleted. 3366   is deleted.
3360   */ 3367   */
3361   key_value_pair& 3368   key_value_pair&
3362   operator=(key_value_pair const&) = delete; 3369   operator=(key_value_pair const&) = delete;
3363   3370  
3364   /** Destructor. 3371   /** Destructor.
3365   3372  
3366   The value is destroyed and all internally allocated memory is freed. 3373   The value is destroyed and all internally allocated memory is freed.
3367   */ 3374   */
HITCBC 3368   59054 ~key_value_pair() noexcept 3375   59054 ~key_value_pair() noexcept
HITCBC 3369   52301 { 3376   52301 {
HITCBC 3370   59054 auto const& sp = value_.storage(); 3377   59054 auto const& sp = value_.storage();
HITCBC 3371   59054 if(sp.is_not_shared_and_deallocate_is_trivial()) 3378   59054 if(sp.is_not_shared_and_deallocate_is_trivial())
MISUBC 3372   return; 3379   return;
HITCBC 3373   59054 if(key_ == empty_) 3380   59054 if(key_ == empty_)
HITCBC 3374   6753 return; 3381   6753 return;
HITCBC 3375   52301 sp->deallocate(const_cast<char*>(key_), 3382   52301 sp->deallocate(const_cast<char*>(key_),
HITCBC 3376   52301 len_ + 1, alignof(char)); 3383   52301 len_ + 1, alignof(char));
HITCBC 3377   59054 } 3384   59054 }
3378   3385  
3379   /** Constructors. 3386   /** Constructors.
3380   3387  
3381   Construct a key/value pair. 3388   Construct a key/value pair.
3382   3389  
3383   @li **(1)** uses a copy of the characters of `key`, and constructs the 3390   @li **(1)** uses a copy of the characters of `key`, and constructs the
3384   value as if by `value(std::forward<Args>(args)...)`. 3391   value as if by `value(std::forward<Args>(args)...)`.
3385   @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`. 3392   @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
3386   @li **(3)** equivalent to 3393   @li **(3)** equivalent to
3387   `key_value_pair(p.first, std::move(p.second), sp)`. 3394   `key_value_pair(p.first, std::move(p.second), sp)`.
3388   @li **(4)** equivalent to 3395   @li **(4)** equivalent to
3389   `key_value_pair(other.key(), other.value(), sp)`. 3396   `key_value_pair(other.key(), other.value(), sp)`.
3390   @li **(5)** equivalent to 3397   @li **(5)** equivalent to
3391   `key_value_pair(other.key(), other.value(), other.storage())`. 3398   `key_value_pair(other.key(), other.value(), other.storage())`.
3392   @li **(6)** the pair s constructed by acquiring ownership of the 3399   @li **(6)** the pair s constructed by acquiring ownership of the
3393   contents of `other` using move semantics. 3400   contents of `other` using move semantics.
3394   @li **(7)** the pair is constructed by acquiring ownership of the 3401   @li **(7)** the pair is constructed by acquiring ownership of the
3395   contents of `other` using pilfer semantics. This is more efficient 3402   contents of `other` using pilfer semantics. This is more efficient
3396   than move construction, when it is known that the moved-from object 3403   than move construction, when it is known that the moved-from object
3397   will be immediately destroyed afterwards. 3404   will be immediately destroyed afterwards.
3398   3405  
3399   With **(2)**, **(3)**, **(4)** the pair uses the memory resource of 3406   With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
3400   `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of 3407   `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
3401   `other.storage()`. With **(1)** it uses whatever memory resource 3408   `other.storage()`. With **(1)** it uses whatever memory resource
3402   `value(std::forward<Args>(args)...)` would use. In any case the pair 3409   `value(std::forward<Args>(args)...)` would use. In any case the pair
3403   acquires shared ownership of its memory resource 3410   acquires shared ownership of its memory resource
3404   3411  
3405   After **(6)** `other` holds an empty key, and a null value with its 3412   After **(6)** `other` holds an empty key, and a null value with its
3406   current storage pointer. 3413   current storage pointer.
3407   3414  
3408   After **(7)** `other` is not in a usable state and may only be destroyed. 3415   After **(7)** `other` is not in a usable state and may only be destroyed.
3409   3416  
3410   @par Complexity 3417   @par Complexity
3411   Constant. 3418   Constant.
3412   3419  
3413   @par Exception Safety 3420   @par Exception Safety
3414   Strong guarantee. Calls to `memory_resource::allocate` may throw. 3421   Strong guarantee. Calls to `memory_resource::allocate` may throw.
3415   @param key The key string to use. 3422   @param key The key string to use.
3416   @param args Optional arguments forwarded to the @ref value constructor. 3423   @param args Optional arguments forwarded to the @ref value constructor.
3417   3424  
3418   @throw boost::system::system_error The size of the key would exceed 3425   @throw boost::system::system_error The size of the key would exceed
3419   @ref string::max_size. 3426   @ref string::max_size.
3420   3427  
3421   @see @ref pilfer, 3428   @see @ref pilfer,
3422   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html). 3429   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
3423   3430  
3424   @{ 3431   @{
3425   */ 3432   */
3426   template<class... Args> 3433   template<class... Args>
3427   explicit 3434   explicit
HITCBC 3428   7885 key_value_pair( 3435   7885 key_value_pair(
3429   string_view key, 3436   string_view key,
3430   Args&&... args) 3437   Args&&... args)
HITCBC 3431   7886 : value_(std::forward<Args>(args)...) 3438   7886 : value_(std::forward<Args>(args)...)
3432   { 3439   {
HITCBC 3433   7884 if(key.size() > string::max_size()) 3440   7884 if(key.size() > string::max_size())
3434   { 3441   {
3435   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 3442   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 3436   1 detail::throw_system_error( error::key_too_large, &loc ); 3443   1 detail::throw_system_error( error::key_too_large, &loc );
3437   } 3444   }
3438   auto s = reinterpret_cast< 3445   auto s = reinterpret_cast<
HITCBC 3439   7883 char*>(value_.storage()-> 3446   7883 char*>(value_.storage()->
HITCBC 3440   7883 allocate(key.size() + 1, alignof(char))); 3447   7883 allocate(key.size() + 1, alignof(char)));
HITCBC 3441   7577 std::memcpy(s, key.data(), key.size()); 3448   7577 std::memcpy(s, key.data(), key.size());
HITCBC 3442   7577 s[key.size()] = 0; 3449   7577 s[key.size()] = 0;
HITCBC 3443   7577 key_ = s; 3450   7577 key_ = s;
HITCBC 3444   7577 len_ = static_cast< 3451   7577 len_ = static_cast<
HITCBC 3445   7577 std::uint32_t>(key.size()); 3452   7577 std::uint32_t>(key.size());
HITCBC 3446   7884 } 3453   7884 }
3447   3454  
3448   /** Overload 3455   /** Overload
3449   3456  
3450   @param p A `std::pair` with the key string and @ref value to construct 3457   @param p A `std::pair` with the key string and @ref value to construct
3451   with. 3458   with.
3452   @param sp A pointer to the @ref boost::container::pmr::memory_resource 3459   @param sp A pointer to the @ref boost::container::pmr::memory_resource
3453   to use. 3460   to use.
3454   */ 3461   */
3455   explicit 3462   explicit
MISUBC 3456   key_value_pair( 3463   key_value_pair(
3457   std::pair< 3464   std::pair<
3458   string_view, 3465   string_view,
3459   json::value> const& p, 3466   json::value> const& p,
3460   storage_ptr sp = {}) 3467   storage_ptr sp = {})
MISUBC 3461   : key_value_pair( 3468   : key_value_pair(
3462   p.first, 3469   p.first,
MISUBC 3463   p.second, 3470   p.second,
MISUBC 3464   std::move(sp)) 3471   std::move(sp))
3465   { 3472   {
MISUBC 3466   } 3473   }
3467   3474  
3468   /// Overload 3475   /// Overload
3469   explicit 3476   explicit
HITCBC 3470   3125 key_value_pair( 3477   3125 key_value_pair(
3471   std::pair< 3478   std::pair<
3472   string_view, 3479   string_view,
3473   json::value>&& p, 3480   json::value>&& p,
3474   storage_ptr sp = {}) 3481   storage_ptr sp = {})
HITCBC 3475   3125 : key_value_pair( 3482   3125 : key_value_pair(
3476   p.first, 3483   p.first,
HITCBC 3477   3125 std::move(p).second, 3484   3125 std::move(p).second,
HITCBC 3478   6250 std::move(sp)) 3485   6250 std::move(sp))
3479   { 3486   {
HITCBC 3480   2978 } 3487   2978 }
3481   3488  
3482   /** Overload 3489   /** Overload
3483   3490  
3484   @param other Another key/value pair. 3491   @param other Another key/value pair.
3485   @param sp 3492   @param sp
3486   */ 3493   */
3487   BOOST_JSON_DECL 3494   BOOST_JSON_DECL
3488   key_value_pair( 3495   key_value_pair(
3489   key_value_pair const& other, 3496   key_value_pair const& other,
3490   storage_ptr sp); 3497   storage_ptr sp);
3491   3498  
3492   /// Overload 3499   /// Overload
HITCBC 3493   758 key_value_pair( 3500   758 key_value_pair(
3494   key_value_pair const& other) 3501   key_value_pair const& other)
HITCBC 3495   758 : key_value_pair(other, 3502   758 : key_value_pair(other,
HITCBC 3496   758 other.storage()) 3503   758 other.storage())
3497   { 3504   {
HITCBC 3498   758 } 3505   758 }
3499   3506  
3500   /// Overload 3507   /// Overload
HITCBC 3501   1 key_value_pair( 3508   1 key_value_pair(
3502   key_value_pair&& other) noexcept 3509   key_value_pair&& other) noexcept
HITCBC 3503   1 : value_(std::move(other.value_)) 3510   1 : value_(std::move(other.value_))
HITCBC 3504   2 , key_(detail::exchange( 3511   2 , key_(detail::exchange(
HITCBC 3505   1 other.key_, empty_)) 3512   1 other.key_, empty_))
HITCBC 3506   2 , len_(detail::exchange( 3513   2 , len_(detail::exchange(
HITCBC 3507   1 other.len_, 0)) 3514   1 other.len_, 0))
3508   { 3515   {
HITCBC 3509   1 } 3516   1 }
3510   3517  
3511   /// Overload 3518   /// Overload
HITCBC 3512   6752 key_value_pair( 3519   6752 key_value_pair(
3513   pilfered<key_value_pair> other) noexcept 3520   pilfered<key_value_pair> other) noexcept
HITCBC 3514   6752 : value_(pilfer(other.get().value_)) 3521   6752 : value_(pilfer(other.get().value_))
HITCBC 3515   13504 , key_(detail::exchange( 3522   13504 , key_(detail::exchange(
HITCBC 3516   6752 other.get().key_, empty_)) 3523   6752 other.get().key_, empty_))
HITCBC 3517   13504 , len_(detail::exchange( 3524   13504 , len_(detail::exchange(
HITCBC 3518   6752 other.get().len_, 0)) 3525   6752 other.get().len_, 0))
3519   { 3526   {
HITCBC 3520   6752 } 3527   6752 }
3521   /// @} 3528   /// @}
3522   3529  
3523   /** The associated memory resource. 3530   /** The associated memory resource.
3524   3531  
3525   Returns a pointer to the memory resource used to construct the value. 3532   Returns a pointer to the memory resource used to construct the value.
3526   3533  
3527   @par Complexity 3534   @par Complexity
3528   Constant. 3535   Constant.
3529   3536  
3530   @par Exception Safety 3537   @par Exception Safety
3531   No-throw guarantee. 3538   No-throw guarantee.
3532   */ 3539   */
3533   storage_ptr const& 3540   storage_ptr const&
HITCBC 3534   758 storage() const noexcept 3541   758 storage() const noexcept
3535   { 3542   {
HITCBC 3536   758 return value_.storage(); 3543   758 return value_.storage();
3537   } 3544   }
3538   3545  
3539   /** The pair's key. 3546   /** The pair's key.
3540   3547  
3541   After construction, the key may not be modified. 3548   After construction, the key may not be modified.
3542   3549  
3543   @par Complexity 3550   @par Complexity
3544   Constant. 3551   Constant.
3545   3552  
3546   @par Exception Safety 3553   @par Exception Safety
3547   No-throw guarantee. 3554   No-throw guarantee.
3548   */ 3555   */
3549   string_view const 3556   string_view const
HITCBC 3550   142971 key() const noexcept 3557   143689 key() const noexcept
3551   { 3558   {
HITCBC 3552   142971 return { key_, len_ }; 3559   143689 return { key_, len_ };
3553   } 3560   }
3554   3561  
3555   /** The pair's key as a null-terminated string. 3562   /** The pair's key as a null-terminated string.
3556   3563  
3557   @par Complexity 3564   @par Complexity
3558   Constant. 3565   Constant.
3559   3566  
3560   @par Exception Safety 3567   @par Exception Safety
3561   No-throw guarantee. 3568   No-throw guarantee.
3562   */ 3569   */
3563   char const* 3570   char const*
HITCBC 3564   1 key_c_str() const noexcept 3571   1 key_c_str() const noexcept
3565   { 3572   {
HITCBC 3566   1 return key_; 3573   1 return key_;
3567   } 3574   }
3568   3575  
3569   /** The pair's value. 3576   /** The pair's value.
3570   3577  
3571   @par Complexity 3578   @par Complexity
3572   Constant. 3579   Constant.
3573   3580  
3574   @par Exception Safety 3581   @par Exception Safety
3575   No-throw guarantee. 3582   No-throw guarantee.
3576   3583  
3577   @{ 3584   @{
3578   */ 3585   */
3579   json::value const& 3586   json::value const&
HITCBC 3580   65222 value() const& noexcept 3587   65222 value() const& noexcept
3581   { 3588   {
HITCBC 3582   65222 return value_; 3589   65222 return value_;
3583   } 3590   }
3584   3591  
3585   json::value&& 3592   json::value&&
3586   value() && noexcept 3593   value() && noexcept
3587   { 3594   {
3588   return std::move( value() ); 3595   return std::move( value() );
3589   } 3596   }
3590   3597  
3591   json::value& 3598   json::value&
HITCBC 3592   1078 value() & noexcept 3599   1078 value() & noexcept
3593   { 3600   {
HITCBC 3594   1078 return value_; 3601   1078 return value_;
3595   } 3602   }
3596   /// @} 3603   /// @}
3597   3604  
3598   private: 3605   private:
3599   json::value value_; 3606   json::value value_;
3600   char const* key_; 3607   char const* key_;
3601   std::uint32_t len_; 3608   std::uint32_t len_;
3602   std::uint32_t next_; 3609   std::uint32_t next_;
3603   }; 3610   };
3604   3611  
3605   //---------------------------------------------------------- 3612   //----------------------------------------------------------
3606   3613  
3607   #ifdef BOOST_JSON_DOCS 3614   #ifdef BOOST_JSON_DOCS
3608   3615  
3609   /** Tuple-like element access. 3616   /** Tuple-like element access.
3610   3617  
3611   This overload of `get` permits the key and value of a @ref key_value_pair 3618   This overload of `get` permits the key and value of a @ref key_value_pair
3612   to be accessed by index. For example: 3619   to be accessed by index. For example:
3613   3620  
3614   @code 3621   @code
3615   key_value_pair kvp("num", 42); 3622   key_value_pair kvp("num", 42);
3616   string_view key = get<0>(kvp); 3623   string_view key = get<0>(kvp);
3617   value& jv = get<1>(kvp); 3624   value& jv = get<1>(kvp);
3618   @endcode 3625   @endcode
3619   3626  
3620   @par Structured Bindings 3627   @par Structured Bindings
3621   When using C++17 or greater, objects of type @ref key_value_pair may be 3628   When using C++17 or greater, objects of type @ref key_value_pair may be
3622   used to initialize structured bindings: 3629   used to initialize structured bindings:
3623   3630  
3624   @code 3631   @code
3625   key_value_pair kvp("num", 42); 3632   key_value_pair kvp("num", 42);
3626   auto& [key, value] = kvp; 3633   auto& [key, value] = kvp;
3627   @endcode 3634   @endcode
3628   3635  
3629   Depending on the value of `I`, the return type will be: 3636   Depending on the value of `I`, the return type will be:
3630   3637  
3631   @li `string_view const` if `I == 0`, or 3638   @li `string_view const` if `I == 0`, or
3632   @li `value&`, `value const&`, or `value&&` if `I == 1`. 3639   @li `value&`, `value const&`, or `value&&` if `I == 1`.
3633   3640  
3634   Using any other value for `I` is ill-formed. 3641   Using any other value for `I` is ill-formed.
3635   3642  
3636   @par Constraints 3643   @par Constraints
3637   `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >` 3644   `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3638   3645  
3639   @tparam I The element index to access. 3646   @tparam I The element index to access.
3640   3647  
3641   @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`. 3648   @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
3642   3649  
3643   @param kvp The @ref key_value_pair object to access. 3650   @param kvp The @ref key_value_pair object to access.
3644   */ 3651   */
3645   template< 3652   template<
3646   std::size_t I, 3653   std::size_t I,
3647   class T> 3654   class T>
3648   __see_below__ 3655   __see_below__
3649   get(T&& kvp) noexcept; 3656   get(T&& kvp) noexcept;
3650   3657  
3651   #else 3658   #else
3652   3659  
3653   template<std::size_t I> 3660   template<std::size_t I>
3654   auto 3661   auto
3655   get(key_value_pair const&) noexcept -> 3662   get(key_value_pair const&) noexcept ->
3656   typename std::conditional<I == 0, 3663   typename std::conditional<I == 0,
3657   string_view const, 3664   string_view const,
3658   value const&>::type 3665   value const&>::type
3659   { 3666   {
3660   static_assert(I == 0, 3667   static_assert(I == 0,
3661   "key_value_pair index out of range"); 3668   "key_value_pair index out of range");
3662   } 3669   }
3663   3670  
3664   template<std::size_t I> 3671   template<std::size_t I>
3665   auto 3672   auto
3666   get(key_value_pair&) noexcept -> 3673   get(key_value_pair&) noexcept ->
3667   typename std::conditional<I == 0, 3674   typename std::conditional<I == 0,
3668   string_view const, 3675   string_view const,
3669   value&>::type 3676   value&>::type
3670   { 3677   {
3671   static_assert(I == 0, 3678   static_assert(I == 0,
3672   "key_value_pair index out of range"); 3679   "key_value_pair index out of range");
3673   } 3680   }
3674   3681  
3675   template<std::size_t I> 3682   template<std::size_t I>
3676   auto 3683   auto
3677   get(key_value_pair&&) noexcept -> 3684   get(key_value_pair&&) noexcept ->
3678   typename std::conditional<I == 0, 3685   typename std::conditional<I == 0,
3679   string_view const, 3686   string_view const,
3680   value&&>::type 3687   value&&>::type
3681   { 3688   {
3682   static_assert(I == 0, 3689   static_assert(I == 0,
3683   "key_value_pair index out of range"); 3690   "key_value_pair index out of range");
3684   } 3691   }
3685   3692  
3686   /** Extracts a key_value_pair's key using tuple-like interface 3693   /** Extracts a key_value_pair's key using tuple-like interface
3687   */ 3694   */
3688   template<> 3695   template<>
3689   inline 3696   inline
3690   string_view const 3697   string_view const
HITCBC 3691   19609 get<0>(key_value_pair const& kvp) noexcept 3698   19609 get<0>(key_value_pair const& kvp) noexcept
3692   { 3699   {
HITCBC 3693   19609 return kvp.key(); 3700   19609 return kvp.key();
3694   } 3701   }
3695   3702  
3696   /** Extracts a key_value_pair's key using tuple-like interface 3703   /** Extracts a key_value_pair's key using tuple-like interface
3697   */ 3704   */
3698   template<> 3705   template<>
3699   inline 3706   inline
3700   string_view const 3707   string_view const
HITCBC 3701   7 get<0>(key_value_pair& kvp) noexcept 3708   7 get<0>(key_value_pair& kvp) noexcept
3702   { 3709   {
HITCBC 3703   7 return kvp.key(); 3710   7 return kvp.key();
3704   } 3711   }
3705   3712  
3706   /** Extracts a key_value_pair's key using tuple-like interface 3713   /** Extracts a key_value_pair's key using tuple-like interface
3707   */ 3714   */
3708   template<> 3715   template<>
3709   inline 3716   inline
3710   string_view const 3717   string_view const
3711   get<0>(key_value_pair&& kvp) noexcept 3718   get<0>(key_value_pair&& kvp) noexcept
3712   { 3719   {
3713   return kvp.key(); 3720   return kvp.key();
3714   } 3721   }
3715   3722  
3716   /** Extracts a key_value_pair's value using tuple-like interface 3723   /** Extracts a key_value_pair's value using tuple-like interface
3717   */ 3724   */
3718   template<> 3725   template<>
3719   inline 3726   inline
3720   value const& 3727   value const&
HITCBC 3721   28299 get<1>(key_value_pair const& kvp) noexcept 3728   28299 get<1>(key_value_pair const& kvp) noexcept
3722   { 3729   {
HITCBC 3723   28299 return kvp.value(); 3730   28299 return kvp.value();
3724   } 3731   }
3725   3732  
3726   /** Extracts a key_value_pair's value using tuple-like interface 3733   /** Extracts a key_value_pair's value using tuple-like interface
3727   */ 3734   */
3728   template<> 3735   template<>
3729   inline 3736   inline
3730   value& 3737   value&
HITCBC 3731   7 get<1>(key_value_pair& kvp) noexcept 3738   7 get<1>(key_value_pair& kvp) noexcept
3732   { 3739   {
HITCBC 3733   7 return kvp.value(); 3740   7 return kvp.value();
3734   } 3741   }
3735   3742  
3736   /** Extracts a key_value_pair's value using tuple-like interface 3743   /** Extracts a key_value_pair's value using tuple-like interface
3737   */ 3744   */
3738   template<> 3745   template<>
3739   inline 3746   inline
3740   value&& 3747   value&&
3741   get<1>(key_value_pair&& kvp) noexcept 3748   get<1>(key_value_pair&& kvp) noexcept
3742   { 3749   {
3743   return std::move(kvp.value()); 3750   return std::move(kvp.value());
3744   } 3751   }
3745   3752  
3746   #endif 3753   #endif
3747   3754  
3748   } // namespace json 3755   } // namespace json
3749   } // namespace boost 3756   } // namespace boost
3750   3757  
3751   #ifdef __clang__ 3758   #ifdef __clang__
3752   # pragma clang diagnostic push 3759   # pragma clang diagnostic push
3753   # pragma clang diagnostic ignored "-Wmismatched-tags" 3760   # pragma clang diagnostic ignored "-Wmismatched-tags"
3754   #endif 3761   #endif
3755   3762  
3756   #ifndef BOOST_JSON_DOCS 3763   #ifndef BOOST_JSON_DOCS
3757   3764  
3758   namespace std { 3765   namespace std {
3759   3766  
3760   /** Tuple-like size access for key_value_pair 3767   /** Tuple-like size access for key_value_pair
3761   */ 3768   */
3762   template<> 3769   template<>
3763   struct tuple_size< ::boost::json::key_value_pair > 3770   struct tuple_size< ::boost::json::key_value_pair >
3764   : std::integral_constant<std::size_t, 2> 3771   : std::integral_constant<std::size_t, 2>
3765   { 3772   {
3766   }; 3773   };
3767   3774  
3768   /** Tuple-like access for the key type of key_value_pair 3775   /** Tuple-like access for the key type of key_value_pair
3769   */ 3776   */
3770   template<> 3777   template<>
3771   struct tuple_element<0, ::boost::json::key_value_pair> 3778   struct tuple_element<0, ::boost::json::key_value_pair>
3772   { 3779   {
3773   using type = ::boost::json::string_view const; 3780   using type = ::boost::json::string_view const;
3774   }; 3781   };
3775   3782  
3776   /** Tuple-like access for the value type of key_value_pair 3783   /** Tuple-like access for the value type of key_value_pair
3777   */ 3784   */
3778   template<> 3785   template<>
3779   struct tuple_element<1, ::boost::json::key_value_pair> 3786   struct tuple_element<1, ::boost::json::key_value_pair>
3780   { 3787   {
3781   using type = ::boost::json::value&; 3788   using type = ::boost::json::value&;
3782   }; 3789   };
3783   3790  
3784   /** Tuple-like access for the value type of key_value_pair 3791   /** Tuple-like access for the value type of key_value_pair
3785   */ 3792   */
3786   template<> 3793   template<>
3787   struct tuple_element<1, ::boost::json::key_value_pair const> 3794   struct tuple_element<1, ::boost::json::key_value_pair const>
3788   { 3795   {
3789   using type = ::boost::json::value const&; 3796   using type = ::boost::json::value const&;
3790   }; 3797   };
3791   3798  
3792   } // std 3799   } // std
3793   3800  
3794   #endif 3801   #endif
3795   3802  
3796   // std::hash specialization 3803   // std::hash specialization
3797   #ifndef BOOST_JSON_DOCS 3804   #ifndef BOOST_JSON_DOCS
3798   namespace std { 3805   namespace std {
3799   template <> 3806   template <>
3800   struct hash< ::boost::json::value > { 3807   struct hash< ::boost::json::value > {
3801   BOOST_JSON_DECL 3808   BOOST_JSON_DECL
3802   std::size_t 3809   std::size_t
3803   operator()(::boost::json::value const& jv) const noexcept; 3810   operator()(::boost::json::value const& jv) const noexcept;
3804   }; 3811   };
3805   } // std 3812   } // std
3806   #endif 3813   #endif
3807   3814  
3808   3815  
3809   #ifdef __clang__ 3816   #ifdef __clang__
3810   # pragma clang diagnostic pop 3817   # pragma clang diagnostic pop
3811   #endif 3818   #endif
3812   3819  
3813   // These are here because value, array, 3820   // These are here because value, array,
3814   // and object form cyclic references. 3821   // and object form cyclic references.
3815   3822  
3816   #include <boost/json/detail/impl/array.hpp> 3823   #include <boost/json/detail/impl/array.hpp>
3817   #include <boost/json/impl/array.hpp> 3824   #include <boost/json/impl/array.hpp>
3818   #include <boost/json/impl/object.hpp> 3825   #include <boost/json/impl/object.hpp>
3819   #include <boost/json/impl/value.hpp> 3826   #include <boost/json/impl/value.hpp>
3820   3827  
3821   // These must come after array and object 3828   // These must come after array and object
3822   #include <boost/json/impl/value_ref.hpp> 3829   #include <boost/json/impl/value_ref.hpp>
3823   3830  
3824   #endif 3831   #endif