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   208 value() noexcept 227   208 value() noexcept
HITCBC 228   208 : sca_() 228   208 : sca_()
229   { 229   {
HITCBC 230   208 } 230   208 }
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   4609682 kind() const noexcept 1168   4609682 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   4609682 sca_.k) & 0x3f); 1172   4609682 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   @throws boost::system::system_error Overload **(3)** reports errors by 1724   @throws boost::system::system_error Overload **(3)** reports errors by
1725   throwing an exception. 1725   throwing an exception.
1726   */ 1726   */
1727   template<class T> 1727   template<class T>
1728   #ifdef BOOST_JSON_DOCS 1728   #ifdef BOOST_JSON_DOCS
1729   T 1729   T
1730   #else 1730   #else
1731   typename std::enable_if< 1731   typename std::enable_if<
1732   std::is_arithmetic<T>::value && 1732   std::is_arithmetic<T>::value &&
1733   ! std::is_same<T, bool>::value, 1733   ! std::is_same<T, bool>::value,
1734   T>::type 1734   T>::type
1735   #endif 1735   #endif
HITCBC 1736   194 to_number() const 1736   194 to_number() const
1737   { 1737   {
HITCBC 1738   194 return try_to_number<T>().value(); 1738   194 return try_to_number<T>().value();
1739   } 1739   }
1740   /// @} 1740   /// @}
1741   1741  
1742   /** Return the stored number as @ref boost::system::result. 1742   /** Return the stored number as @ref boost::system::result.
1743   1743  
1744   This function attempts to return the stored value converted to the 1744   This function attempts to return the stored value converted to the
1745   arithmetic type `T` which may not be `bool`: 1745   arithmetic type `T` which may not be `bool`:
1746   1746  
1747   @li If `T` is an integral type and the stored value is a number which 1747   @li If `T` is an integral type and the stored value is a number which
1748   can be losslessly converted, the conversion is performed without 1748   can be losslessly converted, the conversion is performed without
1749   error and `result<T>` containing the converted number is returned. 1749   error and `result<T>` containing the converted number is returned.
1750   @li If `T` is an integral type and the stored value is a number which 1750   @li If `T` is an integral type and the stored value is a number which
1751   cannot be losslessly converted, then `result<T>` containing the 1751   cannot be losslessly converted, then `result<T>` containing the
1752   corresponding `error_code` is returned. 1752   corresponding `error_code` is returned.
1753   @li If `T` is a floating point type and the stored value is a number, 1753   @li If `T` is a floating point type and the stored value is a number,
1754   the conversion is performed without error. `result<T>` containing 1754   the conversion is performed without error. `result<T>` containing
1755   the converted number, with a possible loss of precision, is 1755   the converted number, with a possible loss of precision, is
1756   returned. 1756   returned.
1757   @li Otherwise, if the stored value is not a number; that is, if 1757   @li Otherwise, if the stored value is not a number; that is, if
1758   `this->is_number()` returns `false`, then `result<T>` containing 1758   `this->is_number()` returns `false`, then `result<T>` containing
1759   the corresponding `error_code` is returned. 1759   the corresponding `error_code` is returned.
1760   1760  
1761   @par Constraints 1761   @par Constraints
1762   @code 1762   @code
1763   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value 1763   std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1764   @endcode 1764   @endcode
1765   1765  
1766   @par Complexity 1766   @par Complexity
1767   Constant. 1767   Constant.
1768   1768  
1769   @par Exception Safety 1769   @par Exception Safety
1770   No-throw guarantee. 1770   No-throw guarantee.
1771   1771  
1772   @return `boost::system::result<T>` with either the converted number or 1772   @return `boost::system::result<T>` with either the converted number or
1773   an `error_code`. 1773   an `error_code`.
1774   */ 1774   */
1775   template<class T> 1775   template<class T>
1776   #ifdef BOOST_JSON_DOCS 1776   #ifdef BOOST_JSON_DOCS
1777   system::result<T> 1777   system::result<T>
1778   #else 1778   #else
1779   typename std::enable_if< 1779   typename std::enable_if<
1780   std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value, 1780   std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
1781   system::result<T> 1781   system::result<T>
1782   >::type 1782   >::type
1783   #endif 1783   #endif
HITCBC 1784   196 try_to_number() const noexcept 1784   196 try_to_number() const noexcept
1785   { 1785   {
HITCBC 1786   196 system::error_code ec; 1786   196 system::error_code ec;
HITCBC 1787   196 T result = to_number<T>(ec); 1787   196 T result = to_number<T>(ec);
HITCBC 1788   196 if( ec ) 1788   196 if( ec )
HITCBC 1789   78 return {system::in_place_error, ec}; 1789   78 return {system::in_place_error, ec};
1790   1790  
HITCBC 1791   118 return {system::in_place_value, result}; 1791   118 return {system::in_place_value, result};
1792   } 1792   }
1793   1793  
1794   //------------------------------------------------------ 1794   //------------------------------------------------------
1795   // 1795   //
1796   // Accessors 1796   // Accessors
1797   // 1797   //
1798   //------------------------------------------------------ 1798   //------------------------------------------------------
1799   1799  
1800   /** Return the associated memory resource. 1800   /** Return the associated memory resource.
1801   1801  
1802   This function returns a smart pointer to the 1802   This function returns a smart pointer to the
1803   @ref boost::container::pmr::memory_resource used by the container. 1803   @ref boost::container::pmr::memory_resource used by the container.
1804   1804  
1805   @par Complexity 1805   @par Complexity
1806   Constant. 1806   Constant.
1807   1807  
1808   @par Exception Safety 1808   @par Exception Safety
1809   No-throw guarantee. 1809   No-throw guarantee.
1810   */ 1810   */
1811   storage_ptr const& 1811   storage_ptr const&
HITCBC 1812   75892 storage() const noexcept 1812   75892 storage() const noexcept
1813   { 1813   {
HITCBC 1814   75892 return sp_; 1814   75892 return sp_;
1815   } 1815   }
1816   1816  
1817   /** Return the associated allocator. 1817   /** Return the associated allocator.
1818   1818  
1819   This function returns an instance of @ref allocator_type constructed 1819   This function returns an instance of @ref allocator_type constructed
1820   from the associated @ref boost::container::pmr::memory_resource. 1820   from the associated @ref boost::container::pmr::memory_resource.
1821   1821  
1822   @par Complexity 1822   @par Complexity
1823   Constant. 1823   Constant.
1824   1824  
1825   @par Exception Safety 1825   @par Exception Safety
1826   No-throw guarantee. 1826   No-throw guarantee.
1827   */ 1827   */
1828   allocator_type 1828   allocator_type
HITCBC 1829   1 get_allocator() const noexcept 1829   1 get_allocator() const noexcept
1830   { 1830   {
HITCBC 1831   1 return sp_.get(); 1831   1 return sp_.get();
1832   } 1832   }
1833   1833  
1834   //------------------------------------------------------ 1834   //------------------------------------------------------
1835   1835  
1836   /** Return `result` with a reference to the underlying @ref array 1836   /** Return `result` with a reference to the underlying @ref array
1837   1837  
1838   If @ref is_array() is `true`, the result contains a reference to the 1838   If @ref is_array() is `true`, the result contains a reference to the
1839   underlying @ref array, otherwise it contains an `error_code`. 1839   underlying @ref array, otherwise it contains an `error_code`.
1840   1840  
1841   @par Example 1841   @par Example
1842   The return value can be used in both a boolean context and 1842   The return value can be used in both a boolean context and
1843   to assign a variable: 1843   to assign a variable:
1844   @code 1844   @code
1845   if( auto r = jv.try_as_array() ) 1845   if( auto r = jv.try_as_array() )
1846   return *r; 1846   return *r;
1847   @endcode 1847   @endcode
1848   1848  
1849   But can also be used to throw an exception on error: 1849   But can also be used to throw an exception on error:
1850   @code 1850   @code
1851   return jv.try_as_array().value(); 1851   return jv.try_as_array().value();
1852   @endcode 1852   @endcode
1853   1853  
1854   @par Complexity 1854   @par Complexity
1855   Constant. 1855   Constant.
1856   1856  
1857   @par Exception Safety 1857   @par Exception Safety
1858   No-throw guarantee. 1858   No-throw guarantee.
1859   1859  
1860   @{ 1860   @{
1861   */ 1861   */
1862   BOOST_JSON_DECL 1862   BOOST_JSON_DECL
1863   system::result<array&> 1863   system::result<array&>
1864   try_as_array() noexcept; 1864   try_as_array() noexcept;
1865   1865  
1866   BOOST_JSON_DECL 1866   BOOST_JSON_DECL
1867   system::result<array const&> 1867   system::result<array const&>
1868   try_as_array() const noexcept; 1868   try_as_array() const noexcept;
1869   /// @} 1869   /// @}
1870   1870  
1871   /** Return `result` with a reference to the underlying @ref object. 1871   /** Return `result` with a reference to the underlying @ref object.
1872   1872  
1873   If @ref is_object() is `true`, the result contains a reference to the 1873   If @ref is_object() is `true`, the result contains a reference to the
1874   underlying @ref object, otherwise it contains an `error_code`. 1874   underlying @ref object, otherwise it contains an `error_code`.
1875   1875  
1876   @par Example 1876   @par Example
1877   The return value can be used in both a boolean context and 1877   The return value can be used in both a boolean context and
1878   to assign a variable: 1878   to assign a variable:
1879   @code 1879   @code
1880   if( auto r = jv.try_as_object() ) 1880   if( auto r = jv.try_as_object() )
1881   return *r; 1881   return *r;
1882   @endcode 1882   @endcode
1883   1883  
1884   But can also be used to throw an exception on error: 1884   But can also be used to throw an exception on error:
1885   @code 1885   @code
1886   return jv.try_as_object().value(); 1886   return jv.try_as_object().value();
1887   @endcode 1887   @endcode
1888   1888  
1889   @par Complexity 1889   @par Complexity
1890   Constant. 1890   Constant.
1891   1891  
1892   @par Exception Safety 1892   @par Exception Safety
1893   No-throw guarantee. 1893   No-throw guarantee.
1894   1894  
1895   @{ 1895   @{
1896   */ 1896   */
1897   BOOST_JSON_DECL 1897   BOOST_JSON_DECL
1898   system::result<object&> 1898   system::result<object&>
1899   try_as_object() noexcept; 1899   try_as_object() noexcept;
1900   1900  
1901   BOOST_JSON_DECL 1901   BOOST_JSON_DECL
1902   system::result<object const&> 1902   system::result<object const&>
1903   try_as_object() const noexcept; 1903   try_as_object() const noexcept;
1904   /// @} 1904   /// @}
1905   1905  
1906   /** Return `result` with a reference to the underlying @ref string. 1906   /** Return `result` with a reference to the underlying @ref string.
1907   1907  
1908   If @ref is_string() is `true`, the result contains a reference to the 1908   If @ref is_string() is `true`, the result contains a reference to the
1909   underlying @ref string, otherwise it contains an `error_code`. 1909   underlying @ref string, otherwise it contains an `error_code`.
1910   1910  
1911   @par Example 1911   @par Example
1912   The return value can be used in both a boolean context and 1912   The return value can be used in both a boolean context and
1913   to assign a variable: 1913   to assign a variable:
1914   @code 1914   @code
1915   if( auto r = jv.try_as_string() ) 1915   if( auto r = jv.try_as_string() )
1916   return *r; 1916   return *r;
1917   @endcode 1917   @endcode
1918   1918  
1919   But can also be used to throw an exception on error: 1919   But can also be used to throw an exception on error:
1920   @code 1920   @code
1921   return jv.try_as_string().value(); 1921   return jv.try_as_string().value();
1922   @endcode 1922   @endcode
1923   1923  
1924   @par Complexity 1924   @par Complexity
1925   Constant. 1925   Constant.
1926   1926  
1927   @par Exception Safety 1927   @par Exception Safety
1928   No-throw guarantee. 1928   No-throw guarantee.
1929   1929  
1930   @{ 1930   @{
1931   */ 1931   */
1932   BOOST_JSON_DECL 1932   BOOST_JSON_DECL
1933   system::result<string&> 1933   system::result<string&>
1934   try_as_string() noexcept; 1934   try_as_string() noexcept;
1935   1935  
1936   BOOST_JSON_DECL 1936   BOOST_JSON_DECL
1937   system::result<string const&> 1937   system::result<string const&>
1938   try_as_string() const noexcept; 1938   try_as_string() const noexcept;
1939   /// @} 1939   /// @}
1940   1940  
1941   /** Return `result` with the underlying `std::int64_t` 1941   /** Return `result` with the underlying `std::int64_t`
1942   1942  
1943   If @ref is_int64() is `true`, the result contains a reference to **(1)** 1943   If @ref is_int64() is `true`, the result contains a reference to **(1)**
1944   or a copy of **(2)** the underlying `std::int64_t`, otherwise it 1944   or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1945   contains an `error_code`. 1945   contains an `error_code`.
1946   1946  
1947   @par Example 1947   @par Example
1948   The return value can be used in both a boolean context and 1948   The return value can be used in both a boolean context and
1949   to assign a variable: 1949   to assign a variable:
1950   @code 1950   @code
1951   if( auto r = jv.try_as_int64() ) 1951   if( auto r = jv.try_as_int64() )
1952   return *r; 1952   return *r;
1953   @endcode 1953   @endcode
1954   1954  
1955   But can also be used to throw an exception on error: 1955   But can also be used to throw an exception on error:
1956   @code 1956   @code
1957   return jv.try_as_int64().value(); 1957   return jv.try_as_int64().value();
1958   @endcode 1958   @endcode
1959   1959  
1960   @par Complexity 1960   @par Complexity
1961   Constant. 1961   Constant.
1962   1962  
1963   @par Exception Safety 1963   @par Exception Safety
1964   No-throw guarantee. 1964   No-throw guarantee.
1965   1965  
1966   @{ 1966   @{
1967   */ 1967   */
1968   BOOST_JSON_DECL 1968   BOOST_JSON_DECL
1969   system::result<std::int64_t&> 1969   system::result<std::int64_t&>
1970   try_as_int64() noexcept; 1970   try_as_int64() noexcept;
1971   1971  
1972   BOOST_JSON_DECL 1972   BOOST_JSON_DECL
1973   system::result<std::int64_t> 1973   system::result<std::int64_t>
1974   try_as_int64() const noexcept; 1974   try_as_int64() const noexcept;
1975   /// @} 1975   /// @}
1976   1976  
1977   /** Return `result` with the underlying `std::uint64_t`. 1977   /** Return `result` with the underlying `std::uint64_t`.
1978   1978  
1979   If @ref is_uint64() is `true`, the result contains a reference to **(1)** 1979   If @ref is_uint64() is `true`, the result contains a reference to **(1)**
1980   or a copy of **(2)** the underlying `std::uint64_t`, otherwise it 1980   or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1981   contains an `error_code`. 1981   contains an `error_code`.
1982   1982  
1983   @par Example 1983   @par Example
1984   The return value can be used in both a boolean context and 1984   The return value can be used in both a boolean context and
1985   to assign a variable: 1985   to assign a variable:
1986   @code 1986   @code
1987   if( auto r = jv.try_as_uint64() ) 1987   if( auto r = jv.try_as_uint64() )
1988   return *r; 1988   return *r;
1989   @endcode 1989   @endcode
1990   1990  
1991   But can also be used to throw an exception on error: 1991   But can also be used to throw an exception on error:
1992   @code 1992   @code
1993   return jv.try_as_uint64().value(); 1993   return jv.try_as_uint64().value();
1994   @endcode 1994   @endcode
1995   1995  
1996   @par Complexity 1996   @par Complexity
1997   Constant. 1997   Constant.
1998   1998  
1999   @par Exception Safety 1999   @par Exception Safety
2000   No-throw guarantee. 2000   No-throw guarantee.
2001   2001  
2002   @{ 2002   @{
2003   */ 2003   */
2004   BOOST_JSON_DECL 2004   BOOST_JSON_DECL
2005   system::result<std::uint64_t&> 2005   system::result<std::uint64_t&>
2006   try_as_uint64() noexcept; 2006   try_as_uint64() noexcept;
2007   2007  
2008   BOOST_JSON_DECL 2008   BOOST_JSON_DECL
2009   system::result<std::uint64_t> 2009   system::result<std::uint64_t>
2010   try_as_uint64() const noexcept; 2010   try_as_uint64() const noexcept;
2011   /// @} 2011   /// @}
2012   2012  
2013   /** Return `result` with the underlying `double` 2013   /** Return `result` with the underlying `double`
2014   2014  
2015   If @ref is_double() is `true`, the result contains a reference to **(1)** 2015   If @ref is_double() is `true`, the result contains a reference to **(1)**
2016   or a copy of **(2)** the underlying `double`, otherwise it 2016   or a copy of **(2)** the underlying `double`, otherwise it
2017   contains an `error_code`. 2017   contains an `error_code`.
2018   2018  
2019   @par Example 2019   @par Example
2020   The return value can be used in both a boolean context and 2020   The return value can be used in both a boolean context and
2021   to assign a variable: 2021   to assign a variable:
2022   @code 2022   @code
2023   if( auto r = jv.try_as_double() ) 2023   if( auto r = jv.try_as_double() )
2024   return *r; 2024   return *r;
2025   @endcode 2025   @endcode
2026   2026  
2027   But can also be used to throw an exception on error: 2027   But can also be used to throw an exception on error:
2028   @code 2028   @code
2029   return jv.try_as_double().value(); 2029   return jv.try_as_double().value();
2030   @endcode 2030   @endcode
2031   2031  
2032   @par Complexity 2032   @par Complexity
2033   Constant. 2033   Constant.
2034   2034  
2035   @par Exception Safety 2035   @par Exception Safety
2036   No-throw guarantee. 2036   No-throw guarantee.
2037   2037  
2038   @{ 2038   @{
2039   */ 2039   */
2040   BOOST_JSON_DECL 2040   BOOST_JSON_DECL
2041   system::result<double&> 2041   system::result<double&>
2042   try_as_double() noexcept; 2042   try_as_double() noexcept;
2043   2043  
2044   BOOST_JSON_DECL 2044   BOOST_JSON_DECL
2045   system::result<double> 2045   system::result<double>
2046   try_as_double() const noexcept; 2046   try_as_double() const noexcept;
2047   /// @} 2047   /// @}
2048   2048  
2049   /** Return `result` with the underlying `bool` 2049   /** Return `result` with the underlying `bool`
2050   2050  
2051   If @ref is_bool() is `true`, the result contains a reference to **(1)** 2051   If @ref is_bool() is `true`, the result contains a reference to **(1)**
2052   or a copy to **(2)** the underlying `bool`, otherwise it contains an 2052   or a copy to **(2)** the underlying `bool`, otherwise it contains an
2053   `error_code`. 2053   `error_code`.
2054   2054  
2055   @par Example 2055   @par Example
2056   The return value can be used in both a boolean context and 2056   The return value can be used in both a boolean context and
2057   to assign a variable: 2057   to assign a variable:
2058   @code 2058   @code
2059   if( auto r = jv.try_as_bool() ) 2059   if( auto r = jv.try_as_bool() )
2060   return *r; 2060   return *r;
2061   @endcode 2061   @endcode
2062   2062  
2063   But can also be used to throw an exception on error: 2063   But can also be used to throw an exception on error:
2064   @code 2064   @code
2065   return jv.try_as_bool().value(); 2065   return jv.try_as_bool().value();
2066   @endcode 2066   @endcode
2067   2067  
2068   @par Complexity 2068   @par Complexity
2069   Constant. 2069   Constant.
2070   2070  
2071   @par Exception Safety 2071   @par Exception Safety
2072   No-throw guarantee. 2072   No-throw guarantee.
2073   2073  
2074   @{ 2074   @{
2075   */ 2075   */
2076   BOOST_JSON_DECL 2076   BOOST_JSON_DECL
2077   system::result<bool&> 2077   system::result<bool&>
2078   try_as_bool() noexcept; 2078   try_as_bool() noexcept;
2079   2079  
2080   BOOST_JSON_DECL 2080   BOOST_JSON_DECL
2081   system::result<bool> 2081   system::result<bool>
2082   try_as_bool() const noexcept; 2082   try_as_bool() const noexcept;
2083   /// @} 2083   /// @}
2084   2084  
2085   /** Return engaged `result` if the `value` is null. 2085   /** Return engaged `result` if the `value` is null.
2086   2086  
2087   If @ref is_null() is `true`, the result is engaged, otherwise it 2087   If @ref is_null() is `true`, the result is engaged, otherwise it
2088   contains an `error_code`. 2088   contains an `error_code`.
2089   2089  
2090   @par Example 2090   @par Example
2091   The return value can be used in both a boolean context and 2091   The return value can be used in both a boolean context and
2092   to assign a variable: 2092   to assign a variable:
2093   @code 2093   @code
2094   if( auto r = jv.try_as_null() ) 2094   if( auto r = jv.try_as_null() )
2095   return *r; 2095   return *r;
2096   @endcode 2096   @endcode
2097   2097  
2098   But can also be used to throw an exception on error: 2098   But can also be used to throw an exception on error:
2099   @code 2099   @code
2100   return jv.try_as_null().value(); 2100   return jv.try_as_null().value();
2101   @endcode 2101   @endcode
2102   2102  
2103   @par Complexity 2103   @par Complexity
2104   Constant. 2104   Constant.
2105   2105  
2106   @par Exception Safety 2106   @par Exception Safety
2107   No-throw guarantee. 2107   No-throw guarantee.
2108   */ 2108   */
2109   BOOST_JSON_DECL 2109   BOOST_JSON_DECL
2110   system::result<std::nullptr_t> 2110   system::result<std::nullptr_t>
2111   try_as_null() const noexcept; 2111   try_as_null() const noexcept;
2112   2112  
2113   //------------------------------------------------------ 2113   //------------------------------------------------------
2114   2114  
2115   /** Return the underlying @ref object, or throw an exception. 2115   /** Return the underlying @ref object, or throw an exception.
2116   2116  
2117   If @ref is_object() is `true`, returns a reference to the underlying 2117   If @ref is_object() is `true`, returns a reference to the underlying
2118   @ref object, otherwise throws an exception. 2118   @ref object, otherwise throws an exception.
2119   2119  
2120   @par Exception Safety 2120   @par Exception Safety
2121   Strong guarantee. 2121   Strong guarantee.
2122   2122  
2123   @throw boost::system::system_error `! this->is_object()`. 2123   @throw boost::system::system_error `! this->is_object()`.
2124   2124  
2125   @param loc @ref boost::source_location to use in thrown exception; the 2125   @param loc @ref boost::source_location to use in thrown exception; the
2126   source location of the call site by default. 2126   source location of the call site by default.
2127   2127  
2128   @par Complexity 2128   @par Complexity
2129   Constant. 2129   Constant.
2130   2130  
2131   @{ 2131   @{
2132   */ 2132   */
2133   object& 2133   object&
HITCBC 2134   167 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) & 2134   167 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2135   { 2135   {
HITCBC 2136   167 auto& self = const_cast<value const&>(*this); 2136   167 auto& self = const_cast<value const&>(*this);
HITCBC 2137   167 return const_cast<object&>( self.as_object(loc) ); 2137   167 return const_cast<object&>( self.as_object(loc) );
2138   } 2138   }
2139   2139  
2140   /// Overload 2140   /// Overload
2141   object&& 2141   object&&
HITCBC 2142   97 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) && 2142   97 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2143   { 2143   {
HITCBC 2144   97 return std::move( as_object(loc) ); 2144   97 return std::move( as_object(loc) );
2145   } 2145   }
2146   2146  
2147   /// Overload 2147   /// Overload
2148   BOOST_JSON_DECL 2148   BOOST_JSON_DECL
2149   object const& 2149   object const&
2150   as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2150   as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2151   /// @} 2151   /// @}
2152   2152  
2153   /** Return the underlying @ref array, or throw an exception. 2153   /** Return the underlying @ref array, or throw an exception.
2154   2154  
2155   If @ref is_array() is `true`, returns a reference to the underlying 2155   If @ref is_array() is `true`, returns a reference to the underlying
2156   @ref array, otherwise throws an exception. 2156   @ref array, otherwise throws an exception.
2157   2157  
2158   @par Exception Safety 2158   @par Exception Safety
2159   Strong guarantee. 2159   Strong guarantee.
2160   2160  
2161   @throw boost::system::system_error `! this->is_array()`. 2161   @throw boost::system::system_error `! this->is_array()`.
2162   2162  
2163   @param loc @ref boost::source_location to use in thrown exception; the 2163   @param loc @ref boost::source_location to use in thrown exception; the
2164   source location of the call site by default. 2164   source location of the call site by default.
2165   2165  
2166   @par Complexity 2166   @par Complexity
2167   Constant. 2167   Constant.
2168   2168  
2169   @{ 2169   @{
2170   */ 2170   */
2171   array& 2171   array&
HITCBC 2172   95 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) & 2172   95 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2173   { 2173   {
HITCBC 2174   95 auto& self = const_cast<value const&>(*this); 2174   95 auto& self = const_cast<value const&>(*this);
HITCBC 2175   95 return const_cast<array&>( self.as_array(loc) ); 2175   95 return const_cast<array&>( self.as_array(loc) );
2176   } 2176   }
2177   2177  
2178   /// Overload 2178   /// Overload
2179   array&& 2179   array&&
HITCBC 2180   10 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) && 2180   10 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2181   { 2181   {
HITCBC 2182   10 return std::move( as_array(loc) ); 2182   10 return std::move( as_array(loc) );
2183   } 2183   }
2184   2184  
2185   /// Overload 2185   /// Overload
2186   BOOST_JSON_DECL 2186   BOOST_JSON_DECL
2187   array const& 2187   array const&
2188   as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2188   as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2189   /// @} 2189   /// @}
2190   2190  
2191   /** Return the underlying @ref string, or throw an exception. 2191   /** Return the underlying @ref string, or throw an exception.
2192   2192  
2193   If @ref is_string() is `true`, returns a reference to the underlying 2193   If @ref is_string() is `true`, returns a reference to the underlying
2194   @ref string, otherwise throws an exception. 2194   @ref string, otherwise throws an exception.
2195   2195  
2196   @par Exception Safety 2196   @par Exception Safety
2197   Strong guarantee. 2197   Strong guarantee.
2198   2198  
2199   @throw boost::system::system_error `! this->is_string()`. 2199   @throw boost::system::system_error `! this->is_string()`.
2200   2200  
2201   @param loc @ref boost::source_location to use in thrown exception; the 2201   @param loc @ref boost::source_location to use in thrown exception; the
2202   source location of the call site by default. 2202   source location of the call site by default.
2203   2203  
2204   @par Complexity 2204   @par Complexity
2205   Constant. 2205   Constant.
2206   2206  
2207   @{ 2207   @{
2208   */ 2208   */
2209   string& 2209   string&
HITCBC 2210   34 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) & 2210   34 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2211   { 2211   {
HITCBC 2212   34 auto& self = const_cast<value const&>(*this); 2212   34 auto& self = const_cast<value const&>(*this);
HITCBC 2213   34 return const_cast<string&>( self.as_string(loc) ); 2213   34 return const_cast<string&>( self.as_string(loc) );
2214   } 2214   }
2215   2215  
2216   /// Overload 2216   /// Overload
2217   string&& 2217   string&&
HITCBC 2218   12 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) && 2218   12 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2219   { 2219   {
HITCBC 2220   12 return std::move( as_string(loc) ); 2220   12 return std::move( as_string(loc) );
2221   } 2221   }
2222   2222  
2223   /// Overload 2223   /// Overload
2224   BOOST_JSON_DECL 2224   BOOST_JSON_DECL
2225   string const& 2225   string const&
2226   as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2226   as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2227   /// @} 2227   /// @}
2228   2228  
2229   /** Return the underlying `std::int64_t`, or throw an exception. 2229   /** Return the underlying `std::int64_t`, or throw an exception.
2230   2230  
2231   If @ref is_int64() is `true`, returns a reference to **(1)** or a copy 2231   If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
2232   of **(2)** the underlying `std::int64_t`, otherwise throws an 2232   of **(2)** the underlying `std::int64_t`, otherwise throws an
2233   exception. 2233   exception.
2234   2234  
2235   @note This function is the intended for direct access to the underlying 2235   @note This function is the intended for direct access to the underlying
2236   object, __if__ it has the type `std::int64_t`. It does not convert the 2236   object, __if__ it has the type `std::int64_t`. It does not convert the
2237   underlying object to the type `std::int64_t` even if a lossless 2237   underlying object to the type `std::int64_t` even if a lossless
2238   conversion is possible. If you are not sure which kind your `value` 2238   conversion is possible. If you are not sure which kind your `value`
2239   has, and you only care about getting a `std::int64_t` number, consider 2239   has, and you only care about getting a `std::int64_t` number, consider
2240   using @ref to_number instead. 2240   using @ref to_number instead.
2241   2241  
2242   @par Exception Safety 2242   @par Exception Safety
2243   Strong guarantee. 2243   Strong guarantee.
2244   2244  
2245   @throw boost::system::system_error `! this->is_int64()`. 2245   @throw boost::system::system_error `! this->is_int64()`.
2246   2246  
2247   @param loc @ref boost::source_location to use in thrown exception; the 2247   @param loc @ref boost::source_location to use in thrown exception; the
2248   source location of the call site by default. 2248   source location of the call site by default.
2249   2249  
2250   @par Complexity 2250   @par Complexity
2251   Constant. 2251   Constant.
2252   2252  
2253   @{ 2253   @{
2254   */ 2254   */
2255   BOOST_JSON_DECL 2255   BOOST_JSON_DECL
2256   std::int64_t& 2256   std::int64_t&
2257   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION); 2257   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
2258   2258  
2259   /// Overload 2259   /// Overload
2260   BOOST_JSON_DECL 2260   BOOST_JSON_DECL
2261   std::int64_t 2261   std::int64_t
2262   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2262   as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2263   /// @} 2263   /// @}
2264   2264  
2265   /** Return the underlying `std::uint64_t`, or throw an exception. 2265   /** Return the underlying `std::uint64_t`, or throw an exception.
2266   2266  
2267   If @ref is_uint64() is `true`, returns a reference to **(1)** or a 2267   If @ref is_uint64() is `true`, returns a reference to **(1)** or a
2268   copy of **(2)** the underlying `std::uint64_t`, otherwise throws an 2268   copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2269   exception. 2269   exception.
2270   2270  
2271   @note This function is intended for direct access to the underlying 2271   @note This function is intended for direct access to the underlying
2272   object, __if__ it has the type `std::uint64_t`. It does not convert the 2272   object, __if__ it has the type `std::uint64_t`. It does not convert the
2273   underlying object to the type `std::uint64_t` even if a lossless 2273   underlying object to the type `std::uint64_t` even if a lossless
2274   conversion is possible. If you are not sure which kind your `value` 2274   conversion is possible. If you are not sure which kind your `value`
2275   has, and you only care about getting a `std::uint64_t` number, consider 2275   has, and you only care about getting a `std::uint64_t` number, consider
2276   using @ref to_number instead. 2276   using @ref to_number instead.
2277   2277  
2278   @par Exception Safety 2278   @par Exception Safety
2279   Strong guarantee. 2279   Strong guarantee.
2280   2280  
2281   @throw boost::system::system_error `! this->is_uint64()`. 2281   @throw boost::system::system_error `! this->is_uint64()`.
2282   2282  
2283   @param loc @ref boost::source_location to use in thrown exception; the 2283   @param loc @ref boost::source_location to use in thrown exception; the
2284   source location of the call site by default. 2284   source location of the call site by default.
2285   2285  
2286   @par Complexity 2286   @par Complexity
2287   Constant. 2287   Constant.
2288   2288  
2289   @{ 2289   @{
2290   */ 2290   */
2291   BOOST_JSON_DECL 2291   BOOST_JSON_DECL
2292   std::uint64_t& 2292   std::uint64_t&
2293   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION); 2293   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
2294   2294  
2295   /// Overload 2295   /// Overload
2296   BOOST_JSON_DECL 2296   BOOST_JSON_DECL
2297   std::uint64_t 2297   std::uint64_t
2298   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2298   as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2299   /// @} 2299   /// @}
2300   2300  
2301   /** Return the underlying `double`, or throw an exception. 2301   /** Return the underlying `double`, or throw an exception.
2302   2302  
2303   If @ref is_double() is `true`, returns a reference to **(1)** or a copy 2303   If @ref is_double() is `true`, returns a reference to **(1)** or a copy
2304   of **(2)** the underlying `double`, otherwise throws an exception. 2304   of **(2)** the underlying `double`, otherwise throws an exception.
2305   2305  
2306   @note This function is intended for direct access to the underlying 2306   @note This function is intended for direct access to the underlying
2307   object, __if__ it has the type `double`. It does not convert the 2307   object, __if__ it has the type `double`. It does not convert the
2308   underlying object to type `double` even if a lossless conversion is 2308   underlying object to type `double` even if a lossless conversion is
2309   possible. If you are not sure which kind your `value` has, and you only 2309   possible. If you are not sure which kind your `value` has, and you only
2310   care about getting a `double` number, consider using @ref to_number 2310   care about getting a `double` number, consider using @ref to_number
2311   instead. 2311   instead.
2312   2312  
2313   @par Exception Safety 2313   @par Exception Safety
2314   Strong guarantee. 2314   Strong guarantee.
2315   2315  
2316   @throw boost::system::system_error `! this->is_double()`. 2316   @throw boost::system::system_error `! this->is_double()`.
2317   2317  
2318   @param loc @ref boost::source_location to use in thrown exception; the 2318   @param loc @ref boost::source_location to use in thrown exception; the
2319   source location of the call site by default. 2319   source location of the call site by default.
2320   2320  
2321   @par Complexity 2321   @par Complexity
2322   Constant. 2322   Constant.
2323   2323  
2324   @{ 2324   @{
2325   */ 2325   */
2326   BOOST_JSON_DECL 2326   BOOST_JSON_DECL
2327   double& 2327   double&
2328   as_double(source_location const& loc = BOOST_CURRENT_LOCATION); 2328   as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
2329   2329  
2330   /// Overload 2330   /// Overload
2331   BOOST_JSON_DECL 2331   BOOST_JSON_DECL
2332   double 2332   double
2333   as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2333   as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2334   /// @} 2334   /// @}
2335   2335  
2336   /** Return the underlying `bool`, or throw an exception. 2336   /** Return the underlying `bool`, or throw an exception.
2337   2337  
2338   If @ref is_bool() is `true`, returns a reference to **(1)** or a copy 2338   If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
2339   of **(2)** the underlying `bool`, otherwise throws an exception. 2339   of **(2)** the underlying `bool`, otherwise throws an exception.
2340   2340  
2341   @par Exception Safety 2341   @par Exception Safety
2342   Strong guarantee. 2342   Strong guarantee.
2343   2343  
2344   @throw boost::system::system_error `! this->is_bool()`. 2344   @throw boost::system::system_error `! this->is_bool()`.
2345   2345  
2346   @param loc @ref boost::source_location to use in thrown exception; the 2346   @param loc @ref boost::source_location to use in thrown exception; the
2347   source location of the call site by default. 2347   source location of the call site by default.
2348   2348  
2349   @par Complexity 2349   @par Complexity
2350   Constant. 2350   Constant.
2351   2351  
2352   @{ 2352   @{
2353   */ 2353   */
2354   BOOST_JSON_DECL 2354   BOOST_JSON_DECL
2355   bool& 2355   bool&
2356   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION); 2356   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
2357   2357  
2358   /// Overload 2358   /// Overload
2359   BOOST_JSON_DECL 2359   BOOST_JSON_DECL
2360   bool 2360   bool
2361   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const; 2361   as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2362   /// @} 2362   /// @}
2363   2363  
2364   //------------------------------------------------------ 2364   //------------------------------------------------------
2365   2365  
2366   /** Return the underlying @ref object, without checking. 2366   /** Return the underlying @ref object, without checking.
2367   2367  
2368   This is the fastest way to access the underlying representation when 2368   This is the fastest way to access the underlying representation when
2369   the kind is known in advance. 2369   the kind is known in advance.
2370   2370  
2371   @par Preconditions 2371   @par Preconditions
2372   2372  
2373   @code 2373   @code
2374   this->is_object() 2374   this->is_object()
2375   @endcode 2375   @endcode
2376   2376  
2377   @par Complexity 2377   @par Complexity
2378   Constant. 2378   Constant.
2379   2379  
2380   @par Exception Safety 2380   @par Exception Safety
2381   No-throw guarantee. 2381   No-throw guarantee.
2382   2382  
2383   @{ 2383   @{
2384   */ 2384   */
2385   object& 2385   object&
HITCBC 2386   40 get_object() & noexcept 2386   40 get_object() & noexcept
2387   { 2387   {
HITCBC 2388   40 BOOST_ASSERT(is_object()); 2388   40 BOOST_ASSERT(is_object());
HITCBC 2389   40 return obj_; 2389   40 return obj_;
2390   } 2390   }
2391   2391  
2392   object&& 2392   object&&
HITCBC 2393   1 get_object() && noexcept 2393   1 get_object() && noexcept
2394   { 2394   {
HITCBC 2395   1 BOOST_ASSERT(is_object()); 2395   1 BOOST_ASSERT(is_object());
HITCBC 2396   1 return std::move(obj_); 2396   1 return std::move(obj_);
2397   } 2397   }
2398   2398  
2399   object const& 2399   object const&
HITCBC 2400   52947 get_object() const& noexcept 2400   52947 get_object() const& noexcept
2401   { 2401   {
HITCBC 2402   52947 BOOST_ASSERT(is_object()); 2402   52947 BOOST_ASSERT(is_object());
HITCBC 2403   52947 return obj_; 2403   52947 return obj_;
2404   } 2404   }
2405   /// @} 2405   /// @}
2406   2406  
2407   /** Return the underlying @ref array, without checking. 2407   /** Return the underlying @ref array, without checking.
2408   2408  
2409   This is the fastest way to access the underlying representation when 2409   This is the fastest way to access the underlying representation when
2410   the kind is known in advance. 2410   the kind is known in advance.
2411   2411  
2412   @par Preconditions 2412   @par Preconditions
2413   2413  
2414   @code 2414   @code
2415   this->is_array() 2415   this->is_array()
2416   @endcode 2416   @endcode
2417   2417  
2418   @par Complexity 2418   @par Complexity
2419   Constant. 2419   Constant.
2420   2420  
2421   @par Exception Safety 2421   @par Exception Safety
2422   No-throw guarantee. 2422   No-throw guarantee.
2423   2423  
2424   @{ 2424   @{
2425   */ 2425   */
2426   array& 2426   array&
HITCBC 2427   27 get_array() & noexcept 2427   27 get_array() & noexcept
2428   { 2428   {
HITCBC 2429   27 BOOST_ASSERT(is_array()); 2429   27 BOOST_ASSERT(is_array());
HITCBC 2430   27 return arr_; 2430   27 return arr_;
2431   } 2431   }
2432   2432  
2433   array&& 2433   array&&
HITCBC 2434   1 get_array() && noexcept 2434   1 get_array() && noexcept
2435   { 2435   {
HITCBC 2436   1 BOOST_ASSERT(is_array()); 2436   1 BOOST_ASSERT(is_array());
HITCBC 2437   1 return std::move(arr_); 2437   1 return std::move(arr_);
2438   } 2438   }
2439   2439  
2440   array const& 2440   array const&
HITCBC 2441   5702 get_array() const& noexcept 2441   5702 get_array() const& noexcept
2442   { 2442   {
HITCBC 2443   5702 BOOST_ASSERT(is_array()); 2443   5702 BOOST_ASSERT(is_array());
HITCBC 2444   5702 return arr_; 2444   5702 return arr_;
2445   } 2445   }
2446   /// @} 2446   /// @}
2447   2447  
2448   /** Return the underlying @ref string, without checking. 2448   /** Return the underlying @ref string, without checking.
2449   2449  
2450   This is the fastest way to access the underlying representation when 2450   This is the fastest way to access the underlying representation when
2451   the kind is known in advance. 2451   the kind is known in advance.
2452   2452  
2453   @par Preconditions 2453   @par Preconditions
2454   2454  
2455   @code 2455   @code
2456   this->is_string() 2456   this->is_string()
2457   @endcode 2457   @endcode
2458   2458  
2459   @par Complexity 2459   @par Complexity
2460   Constant. 2460   Constant.
2461   2461  
2462   @par Exception Safety 2462   @par Exception Safety
2463   No-throw guarantee. 2463   No-throw guarantee.
2464   2464  
2465   @{ 2465   @{
2466   */ 2466   */
2467   string& 2467   string&
HITCBC 2468   8973 get_string() & noexcept 2468   8973 get_string() & noexcept
2469   { 2469   {
HITCBC 2470   8973 BOOST_ASSERT(is_string()); 2470   8973 BOOST_ASSERT(is_string());
HITCBC 2471   8973 return str_; 2471   8973 return str_;
2472   } 2472   }
2473   2473  
2474   string&& 2474   string&&
HITCBC 2475   1 get_string() && noexcept 2475   1 get_string() && noexcept
2476   { 2476   {
HITCBC 2477   1 BOOST_ASSERT(is_string()); 2477   1 BOOST_ASSERT(is_string());
HITCBC 2478   1 return std::move(str_); 2478   1 return std::move(str_);
2479   } 2479   }
2480   2480  
2481   string const& 2481   string const&
HITCBC 2482   40936 get_string() const& noexcept 2482   40936 get_string() const& noexcept
2483   { 2483   {
HITCBC 2484   40936 BOOST_ASSERT(is_string()); 2484   40936 BOOST_ASSERT(is_string());
HITCBC 2485   40936 return str_; 2485   40936 return str_;
2486   } 2486   }
2487   /// @} 2487   /// @}
2488   2488  
2489   /** Return the underlying `std::int64_t`, without checking. 2489   /** Return the underlying `std::int64_t`, without checking.
2490   2490  
2491   This is the fastest way to access the underlying representation when 2491   This is the fastest way to access the underlying representation when
2492   the kind is known in advance. 2492   the kind is known in advance.
2493   2493  
2494   @par Preconditions 2494   @par Preconditions
2495   2495  
2496   @code 2496   @code
2497   this->is_int64() 2497   this->is_int64()
2498   @endcode 2498   @endcode
2499   2499  
2500   @par Complexity 2500   @par Complexity
2501   Constant. 2501   Constant.
2502   2502  
2503   @par Exception Safety 2503   @par Exception Safety
2504   No-throw guarantee. 2504   No-throw guarantee.
2505   2505  
2506   @{ 2506   @{
2507   */ 2507   */
2508   std::int64_t& 2508   std::int64_t&
HITCBC 2509   3 get_int64() noexcept 2509   3 get_int64() noexcept
2510   { 2510   {
HITCBC 2511   3 BOOST_ASSERT(is_int64()); 2511   3 BOOST_ASSERT(is_int64());
HITCBC 2512   3 return sca_.i; 2512   3 return sca_.i;
2513   } 2513   }
2514   2514  
2515   std::int64_t 2515   std::int64_t
HITCBC 2516   14227 get_int64() const noexcept 2516   14227 get_int64() const noexcept
2517   { 2517   {
HITCBC 2518   14227 BOOST_ASSERT(is_int64()); 2518   14227 BOOST_ASSERT(is_int64());
HITCBC 2519   14227 return sca_.i; 2519   14227 return sca_.i;
2520   } 2520   }
2521   /// @} 2521   /// @}
2522   2522  
2523   /** Return the underlying `std::uint64_t`, without checking. 2523   /** Return the underlying `std::uint64_t`, without checking.
2524   2524  
2525   This is the fastest way to access the underlying representation when 2525   This is the fastest way to access the underlying representation when
2526   the kind is known in advance. 2526   the kind is known in advance.
2527   2527  
2528   @par Preconditions 2528   @par Preconditions
2529   2529  
2530   @code 2530   @code
2531   this->is_uint64() 2531   this->is_uint64()
2532   @endcode 2532   @endcode
2533   2533  
2534   @par Complexity 2534   @par Complexity
2535   Constant. 2535   Constant.
2536   2536  
2537   @par Exception Safety 2537   @par Exception Safety
2538   No-throw guarantee. 2538   No-throw guarantee.
2539   2539  
2540   @{ 2540   @{
2541   */ 2541   */
2542   std::uint64_t& 2542   std::uint64_t&
HITCBC 2543   3 get_uint64() noexcept 2543   3 get_uint64() noexcept
2544   { 2544   {
HITCBC 2545   3 BOOST_ASSERT(is_uint64()); 2545   3 BOOST_ASSERT(is_uint64());
HITCBC 2546   3 return sca_.u; 2546   3 return sca_.u;
2547   } 2547   }
2548   2548  
2549   std::uint64_t 2549   std::uint64_t
HITCBC 2550   195 get_uint64() const noexcept 2550   195 get_uint64() const noexcept
2551   { 2551   {
HITCBC 2552   195 BOOST_ASSERT(is_uint64()); 2552   195 BOOST_ASSERT(is_uint64());
HITCBC 2553   195 return sca_.u; 2553   195 return sca_.u;
2554   } 2554   }
2555   /// @} 2555   /// @}
2556   2556  
2557   /** Return the underlying `double`, without checking. 2557   /** Return the underlying `double`, without checking.
2558   2558  
2559   This is the fastest way to access the underlying 2559   This is the fastest way to access the underlying
2560   representation when the kind is known in advance. 2560   representation when the kind is known in advance.
2561   2561  
2562   @par Preconditions 2562   @par Preconditions
2563   2563  
2564   @code 2564   @code
2565   this->is_double() 2565   this->is_double()
2566   @endcode 2566   @endcode
2567   2567  
2568   @par Complexity 2568   @par Complexity
2569   Constant. 2569   Constant.
2570   2570  
2571   @par Exception Safety 2571   @par Exception Safety
2572   No-throw guarantee. 2572   No-throw guarantee.
2573   2573  
2574   @{ 2574   @{
2575   */ 2575   */
2576   double& 2576   double&
HITCBC 2577   3 get_double() noexcept 2577   3 get_double() noexcept
2578   { 2578   {
HITCBC 2579   3 BOOST_ASSERT(is_double()); 2579   3 BOOST_ASSERT(is_double());
HITCBC 2580   3 return sca_.d; 2580   3 return sca_.d;
2581   } 2581   }
2582   2582  
2583   double 2583   double
HITCBC 2584   39169 get_double() const noexcept 2584   39169 get_double() const noexcept
2585   { 2585   {
HITCBC 2586   39169 BOOST_ASSERT(is_double()); 2586   39169 BOOST_ASSERT(is_double());
HITCBC 2587   39169 return sca_.d; 2587   39169 return sca_.d;
2588   } 2588   }
2589   /// @} 2589   /// @}
2590   2590  
2591   /** Return the underlying `bool`, without checking. 2591   /** Return the underlying `bool`, without checking.
2592   2592  
2593   This is the fastest way to access the underlying representation when 2593   This is the fastest way to access the underlying representation when
2594   the kind is known in advance. 2594   the kind is known in advance.
2595   2595  
2596   @par Preconditions 2596   @par Preconditions
2597   2597  
2598   @code 2598   @code
2599   this->is_bool() 2599   this->is_bool()
2600   @endcode 2600   @endcode
2601   2601  
2602   @par Complexity 2602   @par Complexity
2603   Constant. 2603   Constant.
2604   2604  
2605   @par Exception Safety 2605   @par Exception Safety
2606   No-throw guarantee. 2606   No-throw guarantee.
2607   2607  
2608   @{ 2608   @{
2609   */ 2609   */
2610   bool& 2610   bool&
HITCBC 2611   3 get_bool() noexcept 2611   3 get_bool() noexcept
2612   { 2612   {
HITCBC 2613   3 BOOST_ASSERT(is_bool()); 2613   3 BOOST_ASSERT(is_bool());
HITCBC 2614   3 return sca_.b; 2614   3 return sca_.b;
2615   } 2615   }
2616   2616  
2617   bool 2617   bool
HITCBC 2618   777 get_bool() const noexcept 2618   777 get_bool() const noexcept
2619   { 2619   {
HITCBC 2620   777 BOOST_ASSERT(is_bool()); 2620   777 BOOST_ASSERT(is_bool());
HITCBC 2621   777 return sca_.b; 2621   777 return sca_.b;
2622   } 2622   }
2623   /// @} 2623   /// @}
2624   2624  
2625   //------------------------------------------------------ 2625   //------------------------------------------------------
2626   2626  
2627   /** Access an element, with bounds checking. 2627   /** Access an element, with bounds checking.
2628   2628  
2629   Returns `boost::system::result` containing a reference to the element 2629   Returns `boost::system::result` containing a reference to the element
2630   of the underlying ccontainer, if such element exists. If the underlying 2630   of the underlying ccontainer, if such element exists. If the underlying
2631   value is not a container of the suitable type or the container doesn't 2631   value is not a container of the suitable type or the container doesn't
2632   have a corresponding element the result contains an `error_code`. 2632   have a corresponding element the result contains an `error_code`.
2633   2633  
2634   , if `pos` is within its range. If `pos` is 2634   , if `pos` is within its range. If `pos` is
2635   outside of that range, or the underlying value is not an object the 2635   outside of that range, or the underlying value is not an object the
2636   2636  
2637   Returns @ref boost::system::result containing a reference to the 2637   Returns @ref boost::system::result containing a reference to the
2638   element of the underlying @ref array, if `pos` is within its range. If 2638   element of the underlying @ref array, if `pos` is within its range. If
2639   `pos` is outside of that range, or the underlying value is not an array 2639   `pos` is outside of that range, or the underlying value is not an array
2640   the result contains an `error_code`. 2640   the result contains an `error_code`.
2641   2641  
2642   This function is used to access elements of 2642   This function is used to access elements of
2643   the underlying container, or throw an exception if that could not be 2643   the underlying container, or throw an exception if that could not be
2644   done. 2644   done.
2645   2645  
2646   @li **(1)**, **(2)** require the underlying container to be an 2646   @li **(1)**, **(2)** require the underlying container to be an
2647   @ref object, and look for an element with the key `key`. 2647   @ref object, and look for an element with the key `key`.
2648   @li **(3)**, **(4)** require the underlying container to be an 2648   @li **(3)**, **(4)** require the underlying container to be an
2649   @ref array, and look for an element at index `pos`. 2649   @ref array, and look for an element at index `pos`.
2650   2650  
2651   @par Exception Safety 2651   @par Exception Safety
2652   No-throw guarantee. 2652   No-throw guarantee.
2653   2653  
2654   @param key The key of the element to find. 2654   @param key The key of the element to find.
2655   2655  
2656   @par Complexity 2656   @par Complexity
2657   Constant. 2657   Constant.
2658   2658  
2659   @par Exception Safety 2659   @par Exception Safety
2660   No-throw guarantee. 2660   No-throw guarantee.
2661   2661  
2662   @{ 2662   @{
2663   */ 2663   */
2664   BOOST_JSON_DECL 2664   BOOST_JSON_DECL
2665   boost::system::result<value&> 2665   boost::system::result<value&>
2666   try_at(string_view key) noexcept; 2666   try_at(string_view key) noexcept;
2667   2667  
2668   BOOST_JSON_DECL 2668   BOOST_JSON_DECL
2669   boost::system::result<value const&> 2669   boost::system::result<value const&>
2670   try_at(string_view key) const noexcept; 2670   try_at(string_view key) const noexcept;
2671   2671  
2672   /** Overload 2672   /** Overload
2673   2673  
2674   @param pos A zero-based array index. 2674   @param pos A zero-based array index.
2675   */ 2675   */
2676   BOOST_JSON_DECL 2676   BOOST_JSON_DECL
2677   boost::system::result<value&> 2677   boost::system::result<value&>
2678   try_at(std::size_t pos) noexcept; 2678   try_at(std::size_t pos) noexcept;
2679   2679  
2680   /// Overload 2680   /// Overload
2681   BOOST_JSON_DECL 2681   BOOST_JSON_DECL
2682   boost::system::result<value const&> 2682   boost::system::result<value const&>
2683   try_at(std::size_t pos) const noexcept; 2683   try_at(std::size_t pos) const noexcept;
2684   /// @} 2684   /// @}
2685   2685  
2686   2686  
2687   /** Access an element, with bounds checking. 2687   /** Access an element, with bounds checking.
2688   2688  
2689   This function is used to access elements of 2689   This function is used to access elements of
2690   the underlying container, or throw an exception if that could not be 2690   the underlying container, or throw an exception if that could not be
2691   done. 2691   done.
2692   2692  
2693   @li **(1)**--**(3)** is equivalent to 2693   @li **(1)**--**(3)** is equivalent to
2694   `this->as_object(loc).at(key, loc)`. 2694   `this->as_object(loc).at(key, loc)`.
2695   @li **(4)**--**(6)** is equivalent to 2695   @li **(4)**--**(6)** is equivalent to
2696   `this->as_array(loc).at(pos, loc)`. 2696   `this->as_array(loc).at(pos, loc)`.
2697   2697  
2698   @par Complexity 2698   @par Complexity
2699   Constant. 2699   Constant.
2700   2700  
2701   @par Exception Safety 2701   @par Exception Safety
2702   Strong guarantee. 2702   Strong guarantee.
2703   2703  
2704   @param key The key of the element to find. 2704   @param key The key of the element to find.
2705   @param loc @ref boost::source_location to use in thrown exception; the 2705   @param loc @ref boost::source_location to use in thrown exception; the
2706   source location of the call site by default. 2706   source location of the call site by default.
2707   2707  
2708   @throw boost::system::system_error The underlying type of value is not 2708   @throw boost::system::system_error The underlying type of value is not
2709   the container type corresponding to the first argument (i.e. 2709   the container type corresponding to the first argument (i.e.
2710   using an index with an @ref object). 2710   using an index with an @ref object).
2711   @throw boost::system::system_error An element corresponding to the 2711   @throw boost::system::system_error An element corresponding to the
2712   first argument was not found. 2712   first argument was not found.
2713   2713  
2714   @see @ref as_array, @ref as_object. 2714   @see @ref as_array, @ref as_object.
2715   2715  
2716   @{ 2716   @{
2717   */ 2717   */
2718   value& 2718   value&
HITCBC 2719   13 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) & 2719   13 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
2720   { 2720   {
HITCBC 2721   13 return as_object(loc).at(key, loc); 2721   13 return as_object(loc).at(key, loc);
2722   } 2722   }
2723   2723  
2724   /// Overload 2724   /// Overload
2725   value&& 2725   value&&
HITCBC 2726   1 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) && 2726   1 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2727   { 2727   {
HITCBC 2728   1 return std::move( as_object(loc) ).at(key, loc); 2728   1 return std::move( as_object(loc) ).at(key, loc);
2729   } 2729   }
2730   2730  
2731   /// Overload 2731   /// Overload
2732   value const& 2732   value const&
HITCBC 2733   18 at( 2733   18 at(
2734   string_view key, 2734   string_view key,
2735   source_location const& loc = BOOST_CURRENT_LOCATION) const& 2735   source_location const& loc = BOOST_CURRENT_LOCATION) const&
2736   { 2736   {
HITCBC 2737   18 return as_object(loc).at(key, loc); 2737   18 return as_object(loc).at(key, loc);
2738   } 2738   }
2739   2739  
2740   /** Overload 2740   /** Overload
2741   2741  
2742   @param pos A zero-based array index. 2742   @param pos A zero-based array index.
2743   @param loc 2743   @param loc
2744   */ 2744   */
2745   value & 2745   value &
HITCBC 2746   12 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) & 2746   12 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
2747   { 2747   {
HITCBC 2748   12 return as_array(loc).at(pos, loc); 2748   12 return as_array(loc).at(pos, loc);
2749   } 2749   }
2750   2750  
2751   /// Overload 2751   /// Overload
2752   value&& 2752   value&&
HITCBC 2753   10 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) && 2753   10 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2754   { 2754   {
HITCBC 2755   10 return std::move( as_array(loc) ).at(pos, loc); 2755   10 return std::move( as_array(loc) ).at(pos, loc);
2756   } 2756   }
2757   2757  
2758   /// Overload 2758   /// Overload
2759   value const& 2759   value const&
HITCBC 2760   56 at(std::size_t pos, 2760   56 at(std::size_t pos,
2761   source_location const& loc = BOOST_CURRENT_LOCATION) const& 2761   source_location const& loc = BOOST_CURRENT_LOCATION) const&
2762   { 2762   {
HITCBC 2763   56 return as_array(loc).at(pos, loc); 2763   56 return as_array(loc).at(pos, loc);
2764   } 2764   }
2765   /// @} 2765   /// @}
2766   2766  
2767   /** Access an element via JSON Pointer. 2767   /** Access an element via JSON Pointer.
2768   2768  
2769   This function is used to access a (potentially nested) element of the 2769   This function is used to access a (potentially nested) element of the
2770   value using a JSON Pointer string. 2770   value using a JSON Pointer string.
2771   2771  
2772   @par Complexity 2772   @par Complexity
2773   Linear in the sizes of `ptr` and underlying array, object, or string. 2773   Linear in the sizes of `ptr` and underlying array, object, or string.
2774   2774  
2775   @par Exception Safety 2775   @par Exception Safety
2776   No-throw guarantee. 2776   No-throw guarantee.
2777   2777  
2778   @param ptr JSON Pointer string. 2778   @param ptr JSON Pointer string.
2779   2779  
2780   @return @ref boost::system::result containing either a reference to the 2780   @return @ref boost::system::result containing either a reference to the
2781   element identified by `ptr` or a corresponding `error_code`. 2781   element identified by `ptr` or a corresponding `error_code`.
2782   2782  
2783   @see 2783   @see
2784   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2784   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2785   2785  
2786   @{ 2786   @{
2787   */ 2787   */
2788   BOOST_JSON_DECL 2788   BOOST_JSON_DECL
2789   system::result<value const&> 2789   system::result<value const&>
2790   try_at_pointer(string_view ptr) const noexcept; 2790   try_at_pointer(string_view ptr) const noexcept;
2791   2791  
2792   BOOST_JSON_DECL 2792   BOOST_JSON_DECL
2793   system::result<value&> 2793   system::result<value&>
2794   try_at_pointer(string_view ptr) noexcept; 2794   try_at_pointer(string_view ptr) noexcept;
2795   /// @} 2795   /// @}
2796   2796  
2797   /** Access an element via JSON Pointer. 2797   /** Access an element via JSON Pointer.
2798   2798  
2799   This function is used to access a (potentially nested) element of the 2799   This function is used to access a (potentially nested) element of the
2800   value using a JSON Pointer string. 2800   value using a JSON Pointer string.
2801   2801  
2802   @par Complexity 2802   @par Complexity
2803   Linear in the sizes of `ptr` and the underlying container. 2803   Linear in the sizes of `ptr` and the underlying container.
2804   2804  
2805   @par Exception Safety 2805   @par Exception Safety
2806   Strong guarantee. 2806   Strong guarantee.
2807   2807  
2808   @param ptr JSON Pointer string. 2808   @param ptr JSON Pointer string.
2809   @param loc @ref boost::source_location to use in thrown exception; the 2809   @param loc @ref boost::source_location to use in thrown exception; the
2810   source location of the call site by default. 2810   source location of the call site by default.
2811   2811  
2812   @return reference to the element identified by `ptr`. 2812   @return reference to the element identified by `ptr`.
2813   2813  
2814   @throw boost::system::system_error if an error occurs. 2814   @throw boost::system::system_error if an error occurs.
2815   2815  
2816   @see 2816   @see
2817   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2817   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2818   2818  
2819   @{ 2819   @{
2820   */ 2820   */
2821   BOOST_JSON_DECL 2821   BOOST_JSON_DECL
2822   value const& 2822   value const&
2823   at_pointer( 2823   at_pointer(
2824   string_view ptr, 2824   string_view ptr,
2825   source_location const& loc = BOOST_CURRENT_LOCATION) const&; 2825   source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2826   2826  
2827   /// Overload 2827   /// Overload
2828   inline 2828   inline
2829   value&& 2829   value&&
2830   at_pointer( 2830   at_pointer(
2831   string_view ptr, 2831   string_view ptr,
2832   source_location const& loc = BOOST_CURRENT_LOCATION) &&; 2832   source_location const& loc = BOOST_CURRENT_LOCATION) &&;
2833   2833  
2834   /// Overload 2834   /// Overload
2835   inline 2835   inline
2836   value& 2836   value&
2837   at_pointer( 2837   at_pointer(
2838   string_view ptr, 2838   string_view ptr,
2839   source_location const& loc = BOOST_CURRENT_LOCATION) &; 2839   source_location const& loc = BOOST_CURRENT_LOCATION) &;
2840   /// @} 2840   /// @}
2841   2841  
2842   /** Access an element via JSON Pointer. 2842   /** Access an element via JSON Pointer.
2843   2843  
2844   This function is used to access a (potentially nested) element of the 2844   This function is used to access a (potentially nested) element of the
2845   value using a JSON Pointer string. 2845   value using a JSON Pointer string.
2846   2846  
2847   @par Complexity 2847   @par Complexity
2848   Linear in the sizes of `ptr` and underlying container. 2848   Linear in the sizes of `ptr` and underlying container.
2849   2849  
2850   @par Exception Safety 2850   @par Exception Safety
2851   No-throw guarantee. 2851   No-throw guarantee.
2852   2852  
2853   @param ptr JSON Pointer string. 2853   @param ptr JSON Pointer string.
2854   @param ec Set to the error, if any occurred. 2854   @param ec Set to the error, if any occurred.
2855   2855  
2856   @return pointer to the element identified by `ptr`. 2856   @return pointer to the element identified by `ptr`.
2857   2857  
2858   @see 2858   @see
2859   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901) 2859   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
2860   2860  
2861   @{ 2861   @{
2862   */ 2862   */
2863   BOOST_JSON_DECL 2863   BOOST_JSON_DECL
2864   value const* 2864   value const*
2865   find_pointer(string_view ptr, system::error_code& ec) const noexcept; 2865   find_pointer(string_view ptr, system::error_code& ec) const noexcept;
2866   2866  
2867   BOOST_JSON_DECL 2867   BOOST_JSON_DECL
2868   value* 2868   value*
2869   find_pointer(string_view ptr, system::error_code& ec) noexcept; 2869   find_pointer(string_view ptr, system::error_code& ec) noexcept;
2870   2870  
2871   BOOST_JSON_DECL 2871   BOOST_JSON_DECL
2872   value const* 2872   value const*
2873   find_pointer(string_view ptr, std::error_code& ec) const noexcept; 2873   find_pointer(string_view ptr, std::error_code& ec) const noexcept;
2874   2874  
2875   BOOST_JSON_DECL 2875   BOOST_JSON_DECL
2876   value* 2876   value*
2877   find_pointer(string_view ptr, std::error_code& ec) noexcept; 2877   find_pointer(string_view ptr, std::error_code& ec) noexcept;
2878   /// @} 2878   /// @}
2879   2879  
2880   //------------------------------------------------------ 2880   //------------------------------------------------------
2881   2881  
2882   /** Set an element via JSON Pointer. 2882   /** Set an element via JSON Pointer.
2883   2883  
2884   This function is used to insert or assign to a potentially nested 2884   This function is used to insert or assign to a potentially nested
2885   element of the value using a JSON Pointer string. The function may 2885   element of the value using a JSON Pointer string. The function may
2886   create intermediate elements corresponding to pointer segments. 2886   create intermediate elements corresponding to pointer segments.
2887   2887  
2888   The particular conditions when and what kind of intermediate element 2888   The particular conditions when and what kind of intermediate element
2889   is created is governed by the `ptr` parameter. 2889   is created is governed by the `ptr` parameter.
2890   2890  
2891   Each pointer token is considered in sequence. For each token 2891   Each pointer token is considered in sequence. For each token
2892   2892  
2893   - if the containing value is an @ref object, then a new `null` 2893   - if the containing value is an @ref object, then a new `null`
2894   element is created with key equal to unescaped token string; 2894   element is created with key equal to unescaped token string;
2895   otherwise 2895   otherwise
2896   2896  
2897   - if the containing value is an @ref array, and the token represents a 2897   - if the containing value is an @ref array, and the token represents a
2898   past-the-end marker, then a `null` element is appended to the array; 2898   past-the-end marker, then a `null` element is appended to the array;
2899   otherwise 2899   otherwise
2900   2900  
2901   - if the containing value is an @ref array, and the token represents a 2901   - if the containing value is an @ref array, and the token represents a
2902   number, then if the difference between the number and array's size 2902   number, then if the difference between the number and array's size
2903   is smaller than `opts.max_created_elements`, then the size of the 2903   is smaller than `opts.max_created_elements`, then the size of the
2904   array is increased, so that the number can reference an element in the 2904   array is increased, so that the number can reference an element in the
2905   array; otherwise 2905   array; otherwise
2906   2906  
2907   - if the containing value is of different @ref kind and 2907   - if the containing value is of different @ref kind and
2908   `opts.replace_any_scalar` is `true`, or the value is `null`, then 2908   `opts.replace_any_scalar` is `true`, or the value is `null`, then
2909   2909  
2910   - if `opts.create_arrays` is `true` and the token either represents 2910   - if `opts.create_arrays` is `true` and the token either represents
2911   past-the-end marker or a number, then the value is replaced with 2911   past-the-end marker or a number, then the value is replaced with
2912   an empty array and the token is considered again; otherwise 2912   an empty array and the token is considered again; otherwise
2913   2913  
2914   - if `opts.create_objects` is `true`, then the value is replaced 2914   - if `opts.create_objects` is `true`, then the value is replaced
2915   with an empty object and the token is considered again; otherwise 2915   with an empty object and the token is considered again; otherwise
2916   2916  
2917   - an error is produced. 2917   - an error is produced.
2918   2918  
2919   @par Complexity 2919   @par Complexity
2920   Linear in the sum of size of `ptr`, size of underlying array, object, 2920   Linear in the sum of size of `ptr`, size of underlying array, object,
2921   or string and `opts.max_created_elements`. 2921   or string and `opts.max_created_elements`.
2922   2922  
2923   @par Exception Safety 2923   @par Exception Safety
2924   Basic guarantee. Calls to `memory_resource::allocate` may throw. 2924   Basic guarantee. Calls to `memory_resource::allocate` may throw.
2925   2925  
2926   @param sv JSON Pointer string. 2926   @param sv JSON Pointer string.
2927   @param ref The value to assign to pointed element. 2927   @param ref The value to assign to pointed element.
2928   @param opts The options for the algorithm. 2928   @param opts The options for the algorithm.
2929   2929  
2930   @return @ref boost::system::result containing either a reference to the 2930   @return @ref boost::system::result containing either a reference to the
2931   element identified by `ptr` or a corresponding `error_code`. 2931   element identified by `ptr` or a corresponding `error_code`.
2932   2932  
2933   @see 2933   @see
2934   @ref set_pointer_options, 2934   @ref set_pointer_options,
2935   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901). 2935   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2936   */ 2936   */
2937   BOOST_JSON_DECL 2937   BOOST_JSON_DECL
2938   system::result<value&> 2938   system::result<value&>
2939   try_set_at_pointer( 2939   try_set_at_pointer(
2940   string_view sv, 2940   string_view sv,
2941   value_ref ref, 2941   value_ref ref,
2942   set_pointer_options const& opts = {} ); 2942   set_pointer_options const& opts = {} );
2943   2943  
2944   /** Set an element via JSON Pointer. 2944   /** Set an element via JSON Pointer.
2945   2945  
2946   This function is used to insert or assign to a potentially nested 2946   This function is used to insert or assign to a potentially nested
2947   element of the value using a JSON Pointer string. The function may 2947   element of the value using a JSON Pointer string. The function may
2948   create intermediate elements corresponding to pointer segments. 2948   create intermediate elements corresponding to pointer segments.
2949   2949  
2950   The particular conditions when and what kind of intermediate element 2950   The particular conditions when and what kind of intermediate element
2951   is created is governed by the `ptr` parameter. 2951   is created is governed by the `ptr` parameter.
2952   2952  
2953   Each pointer token is considered in sequence. For each token 2953   Each pointer token is considered in sequence. For each token
2954   2954  
2955   - if the containing value is an @ref object, then a new `null` 2955   - if the containing value is an @ref object, then a new `null`
2956   element is created with key equal to unescaped token string; otherwise 2956   element is created with key equal to unescaped token string; otherwise
2957   2957  
2958   - if the containing value is an @ref array, and the token represents a 2958   - if the containing value is an @ref array, and the token represents a
2959   past-the-end marker, then a `null` element is appended to the array; 2959   past-the-end marker, then a `null` element is appended to the array;
2960   otherwise 2960   otherwise
2961   2961  
2962   - if the containing value is an @ref array, and the token represents a 2962   - if the containing value is an @ref array, and the token represents a
2963   number, then if the difference between the number and array's size 2963   number, then if the difference between the number and array's size
2964   is smaller than `opts.max_created_elements`, then the size of the 2964   is smaller than `opts.max_created_elements`, then the size of the
2965   array is increased, so that the number can reference an element in the 2965   array is increased, so that the number can reference an element in the
2966   array; otherwise 2966   array; otherwise
2967   2967  
2968   - if the containing value is of different @ref kind and 2968   - if the containing value is of different @ref kind and
2969   `opts.replace_any_scalar` is `true`, or the value is `null`, then 2969   `opts.replace_any_scalar` is `true`, or the value is `null`, then
2970   2970  
2971   - if `opts.create_arrays` is `true` and the token either represents 2971   - if `opts.create_arrays` is `true` and the token either represents
2972   past-the-end marker or a number, then the value is replaced with 2972   past-the-end marker or a number, then the value is replaced with
2973   an empty array and the token is considered again; otherwise 2973   an empty array and the token is considered again; otherwise
2974   2974  
2975   - if `opts.create_objects` is `true`, then the value is replaced 2975   - if `opts.create_objects` is `true`, then the value is replaced
2976   with an empty object and the token is considered again; otherwise 2976   with an empty object and the token is considered again; otherwise
2977   2977  
2978   - an error is produced. 2978   - an error is produced.
2979   2979  
2980   @par Complexity 2980   @par Complexity
2981   Linear in the sum of size of `ptr`, size of underlying array, object, 2981   Linear in the sum of size of `ptr`, size of underlying array, object,
2982   or string and `opts.max_created_elements`. 2982   or string and `opts.max_created_elements`.
2983   2983  
2984   @par Exception Safety 2984   @par Exception Safety
2985   Basic guarantee. 2985   Basic guarantee.
2986   Calls to `memory_resource::allocate` may throw. 2986   Calls to `memory_resource::allocate` may throw.
2987   2987  
2988   @param sv JSON Pointer string. 2988   @param sv JSON Pointer string.
2989   2989  
2990   @param ref The value to assign to pointed element. 2990   @param ref The value to assign to pointed element.
2991   2991  
2992   @param opts The options for the algorithm. 2992   @param opts The options for the algorithm.
2993   2993  
2994   @return Reference to the element identified by `ptr`. 2994   @return Reference to the element identified by `ptr`.
2995   2995  
2996   @throws boost::system::system_error Overload **(1)** reports errors by 2996   @throws boost::system::system_error Overload **(1)** reports errors by
2997   throwing exceptions. 2997   throwing exceptions.
2998   2998  
2999   @see @ref set_pointer_options, 2999   @see @ref set_pointer_options,
3000   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">). 3000   [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
3001   3001  
3002   @{ 3002   @{
3003   */ 3003   */
3004   BOOST_JSON_DECL 3004   BOOST_JSON_DECL
3005   value& 3005   value&
3006   set_at_pointer( 3006   set_at_pointer(
3007   string_view sv, 3007   string_view sv,
3008   value_ref ref, 3008   value_ref ref,
3009   set_pointer_options const& opts = {} ); 3009   set_pointer_options const& opts = {} );
3010   3010  
3011   /** Overload 3011   /** Overload
3012   3012  
3013   @param ec Set to the error, if any occurred. 3013   @param ec Set to the error, if any occurred.
3014   @param sv 3014   @param sv
3015   @param ref 3015   @param ref
3016   @param opts 3016   @param opts
3017   */ 3017   */
3018   BOOST_JSON_DECL 3018   BOOST_JSON_DECL
3019   value* 3019   value*
3020   set_at_pointer( 3020   set_at_pointer(
3021   string_view sv, 3021   string_view sv,
3022   value_ref ref, 3022   value_ref ref,
3023   system::error_code& ec, 3023   system::error_code& ec,
3024   set_pointer_options const& opts = {} ); 3024   set_pointer_options const& opts = {} );
3025   3025  
3026   /// Overload 3026   /// Overload
3027   BOOST_JSON_DECL 3027   BOOST_JSON_DECL
3028   value* 3028   value*
3029   set_at_pointer( 3029   set_at_pointer(
3030   string_view sv, 3030   string_view sv,
3031   value_ref ref, 3031   value_ref ref,
3032   std::error_code& ec, 3032   std::error_code& ec,
3033   set_pointer_options const& opts = {} ); 3033   set_pointer_options const& opts = {} );
3034   /// @} 3034   /// @}
3035   3035  
3036   //------------------------------------------------------ 3036   //------------------------------------------------------
3037   3037  
3038   /** Check if two values are equal. 3038   /** Check if two values are equal.
3039   3039  
3040   Two values are equal when they are the same kind and their referenced 3040   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 3041   values are equal, or when they are both integral types and their
3042   integral representations are equal. 3042   integral representations are equal.
3043   3043  
3044   @par Complexity 3044   @par Complexity
3045   Constant or linear in the size of the underlying @ref array, @ref object, 3045   Constant or linear in the size of the underlying @ref array, @ref object,
3046   or @ref string. 3046   or @ref string.
3047   3047  
3048   @par Exception Safety 3048   @par Exception Safety
3049   No-throw guarantee. 3049   No-throw guarantee.
3050   */ 3050   */
3051   // inline friend speeds up overload resolution 3051   // inline friend speeds up overload resolution
3052   friend 3052   friend
3053   bool 3053   bool
HITCBC 3054   4172 operator==( 3054   4172 operator==(
3055   value const& lhs, 3055   value const& lhs,
3056   value const& rhs) noexcept 3056   value const& rhs) noexcept
3057   { 3057   {
HITCBC 3058   4172 return lhs.equal(rhs); 3058   4172 return lhs.equal(rhs);
3059   } 3059   }
3060   3060  
3061   /** Check if two values are not equal. 3061   /** Check if two values are not equal.
3062   3062  
3063   Two values are equal when they are the same kind and their referenced 3063   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 3064   values are equal, or when they are both integral types and their
3065   integral representations are equal. 3065   integral representations are equal.
3066   3066  
3067   @par Complexity 3067   @par Complexity
3068   Constant or linear in the size of the underlying @ref array, 3068   Constant or linear in the size of the underlying @ref array,
3069   @ref object, or @ref string. 3069   @ref object, or @ref string.
3070   3070  
3071   @par Exception Safety 3071   @par Exception Safety
3072   No-throw guarantee. 3072   No-throw guarantee.
3073   */ 3073   */
3074   friend 3074   friend
3075   bool 3075   bool
HITCBC 3076   3989 operator!=( 3076   3989 operator!=(
3077   value const& lhs, 3077   value const& lhs,
3078   value const& rhs) noexcept 3078   value const& rhs) noexcept
3079   { 3079   {
HITCBC 3080   3989 return ! (lhs == rhs); 3080   3989 return ! (lhs == rhs);
3081   } 3081   }
3082   3082  
3083   /** Serialize @ref value to an output stream. 3083   /** Serialize @ref value to an output stream.
3084   3084  
3085   This function serializes a `value` as JSON text into the output stream. 3085   This function serializes a `value` as JSON text into the output stream.
3086   3086  
3087   @return Reference to `os`. 3087   @return Reference to `os`.
3088   3088  
3089   @par Complexity 3089   @par Complexity
3090   Constant or linear in the size of `jv`. 3090   Constant or linear in the size of `jv`.
3091   3091  
3092   @par Exception Safety 3092   @par Exception Safety
3093   Strong guarantee. 3093   Strong guarantee.
3094   Calls to `memory_resource::allocate` may throw. 3094   Calls to `memory_resource::allocate` may throw.
3095   3095  
3096   @param os The output stream to serialize to. 3096   @param os The output stream to serialize to.
3097   3097  
3098   @param jv The value to serialize. 3098   @param jv The value to serialize.
3099   */ 3099   */
3100   BOOST_JSON_DECL 3100   BOOST_JSON_DECL
3101   friend 3101   friend
3102   std::ostream& 3102   std::ostream&
3103   operator<<( 3103   operator<<(
3104   std::ostream& os, 3104   std::ostream& os,
3105   value const& jv); 3105   value const& jv);
3106   3106  
3107   /** Parse @ref value from an input stream. 3107   /** Parse @ref value from an input stream.
3108   3108  
3109   This function parses JSON from an input stream into a `value`. If 3109   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 3110   parsing fails, @ref std::ios_base::failbit will be set for `is` and
3111   `jv` will be left unchanged. Regardless of whether @ref 3111   `jv` will be left unchanged. Regardless of whether @ref
3112   std::ios_base::skipws flag is set on `is`, consumes whitespace before 3112   std::ios_base::skipws flag is set on `is`, consumes whitespace before
3113   and after JSON, because whitespace is considered a part of JSON. 3113   and after JSON, because whitespace is considered a part of JSON.
3114   Behaves as 3114   Behaves as
3115   [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction). 3115   [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
3116   3116  
3117   @note This operator cannot assume that the stream only contains a 3117   @note This operator cannot assume that the stream only contains a
3118   single JSON document, which may result in **very underwhelming 3118   single JSON document, which may result in **very underwhelming
3119   performance**, if the stream isn't cooperative. If you know that your 3119   performance**, if the stream isn't cooperative. If you know that your
3120   input consists of a single JSON document, consider using @ref parse 3120   input consists of a single JSON document, consider using @ref parse
3121   function instead. 3121   function instead.
3122   3122  
3123   @return Reference to `is`. 3123   @return Reference to `is`.
3124   3124  
3125   @par Complexity 3125   @par Complexity
3126   Linear in the size of JSON data. 3126   Linear in the size of JSON data.
3127   3127  
3128   @par Exception Safety 3128   @par Exception Safety
3129   Basic guarantee. 3129   Basic guarantee.
3130   Calls to `memory_resource::allocate` may throw. 3130   Calls to `memory_resource::allocate` may throw.
3131   The stream may throw as configured by @ref std::ios::exceptions. 3131   The stream may throw as configured by @ref std::ios::exceptions.
3132   3132  
3133   @param is The input stream to parse from. 3133   @param is The input stream to parse from.
3134   3134  
3135   @param jv The value to parse into. 3135   @param jv The value to parse into.
3136   3136  
3137   @see @ref parse. 3137   @see @ref parse.
3138   */ 3138   */
3139   BOOST_JSON_DECL 3139   BOOST_JSON_DECL
3140   friend 3140   friend
3141   std::istream& 3141   std::istream&
3142   operator>>( 3142   operator>>(
3143   std::istream& is, 3143   std::istream& is,
3144   value& jv); 3144   value& jv);
3145   3145  
3146   /** Helper for @ref boost::hash support. 3146   /** Helper for @ref boost::hash support.
3147   3147  
3148   Computes a hash value for `jv`. This function is used by 3148   Computes a hash value for `jv`. This function is used by
3149   `boost::hash<value>`. Similar overloads for @ref array, @ref object, 3149   `boost::hash<value>`. Similar overloads for @ref array, @ref object,
3150   and @ref string do not exist, because those types are supported by 3150   and @ref string do not exist, because those types are supported by
3151   `boost::hash` out of the box. 3151   `boost::hash` out of the box.
3152   3152  
3153   @return hash value for `jv`. 3153   @return hash value for `jv`.
3154   3154  
3155   @param jv `value` for which a hash is to be computed. 3155   @param jv `value` for which a hash is to be computed.
3156   3156  
3157   @see [Boost.ContainerHash](https://boost.org/libs/container_hash). 3157   @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
3158   */ 3158   */
3159   #ifndef BOOST_JSON_DOCS 3159   #ifndef BOOST_JSON_DOCS
3160   template< 3160   template<
3161   class T, 3161   class T,
3162   typename std::enable_if< 3162   typename std::enable_if<
3163   std::is_same< detail::remove_cvref<T>, value >::value >::type* 3163   std::is_same< detail::remove_cvref<T>, value >::value >::type*
3164   = nullptr> 3164   = nullptr>
3165   friend 3165   friend
3166   std::size_t 3166   std::size_t
HITCBC 3167   248 hash_value( T const& jv ) noexcept 3167   248 hash_value( T const& jv ) noexcept
3168   #else 3168   #else
3169   friend 3169   friend
3170   inline 3170   inline
3171   std::size_t 3171   std::size_t
3172   hash_value( value const& jv ) noexcept 3172   hash_value( value const& jv ) noexcept
3173   #endif 3173   #endif
3174   { 3174   {
HITCBC 3175   248 return detail::hash_value_impl(jv); 3175   248 return detail::hash_value_impl(jv);
3176   } 3176   }
3177   3177  
3178   private: 3178   private:
3179   static 3179   static
3180   void 3180   void
HITCBC 3181   2133719 relocate( 3181   2133719 relocate(
3182   value* dest, 3182   value* dest,
3183   value const& src) noexcept 3183   value const& src) noexcept
3184   { 3184   {
HITCBC 3185   2133719 std::memcpy( 3185   2133719 std::memcpy(
3186   static_cast<void*>(dest), 3186   static_cast<void*>(dest),
3187   &src, 3187   &src,
3188   sizeof(src)); 3188   sizeof(src));
HITCBC 3189   2133719 } 3189   2133719 }
3190   3190  
3191   BOOST_JSON_DECL 3191   BOOST_JSON_DECL
3192   storage_ptr 3192   storage_ptr
3193   destroy() noexcept; 3193   destroy() noexcept;
3194   3194  
3195   BOOST_JSON_DECL 3195   BOOST_JSON_DECL
3196   bool 3196   bool
3197   equal(value const& other) const noexcept; 3197   equal(value const& other) const noexcept;
3198   3198  
3199   template<class T> 3199   template<class T>
3200   auto 3200   auto
HITCBC 3201   3408 to_number(error& e) const noexcept -> 3201   3408 to_number(error& e) const noexcept ->
3202   typename std::enable_if< 3202   typename std::enable_if<
3203   std::is_signed<T>::value && 3203   std::is_signed<T>::value &&
3204   ! std::is_floating_point<T>::value, 3204   ! std::is_floating_point<T>::value,
3205   T>::type 3205   T>::type
3206   { 3206   {
HITCBC 3207   3408 if(sca_.k == json::kind::int64) 3207   3408 if(sca_.k == json::kind::int64)
3208   { 3208   {
HITCBC 3209   3321 auto const i = sca_.i; 3209   3321 auto const i = sca_.i;
HITCBC 3210   6636 if( i >= (std::numeric_limits<T>::min)() && 3210   6636 if( i >= (std::numeric_limits<T>::min)() &&
HITCBC 3211   3315 i <= (std::numeric_limits<T>::max)()) 3211   3315 i <= (std::numeric_limits<T>::max)())
3212   { 3212   {
HITCBC 3213   3309 e = {}; 3213   3309 e = {};
HITCBC 3214   3309 return static_cast<T>(i); 3214   3309 return static_cast<T>(i);
3215   } 3215   }
HITCBC 3216   12 e = error::not_exact; 3216   12 e = error::not_exact;
3217   } 3217   }
HITCBC 3218   87 else if(sca_.k == json::kind::uint64) 3218   87 else if(sca_.k == json::kind::uint64)
3219   { 3219   {
HITCBC 3220   20 auto const u = sca_.u; 3220   20 auto const u = sca_.u;
HITCBC 3221   20 if(u <= static_cast<std::uint64_t>(( 3221   20 if(u <= static_cast<std::uint64_t>((
HITCBC 3222   20 std::numeric_limits<T>::max)())) 3222   20 std::numeric_limits<T>::max)()))
3223   { 3223   {
HITCBC 3224   10 e = {}; 3224   10 e = {};
HITCBC 3225   10 return static_cast<T>(u); 3225   10 return static_cast<T>(u);
3226   } 3226   }
HITCBC 3227   10 e = error::not_exact; 3227   10 e = error::not_exact;
3228   } 3228   }
HITCBC 3229   67 else if(sca_.k == json::kind::double_) 3229   67 else if(sca_.k == json::kind::double_)
3230   { 3230   {
HITCBC 3231   20 auto const d = sca_.d; 3231   20 auto const d = sca_.d;
HITCBC 3232   20 if( d >= static_cast<double>( 3232   20 if( d >= static_cast<double>(
HITCBC 3233   40 (detail::to_number_limit<T>::min)()) && 3233   40 (detail::to_number_limit<T>::min)()) &&
3234   d <= static_cast<double>( 3234   d <= static_cast<double>(
HITCBC 3235   40 (detail::to_number_limit<T>::max)()) && 3235   40 (detail::to_number_limit<T>::max)()) &&
HITCBC 3236   20 static_cast<T>(d) == d) 3236   20 static_cast<T>(d) == d)
3237   { 3237   {
HITCBC 3238   9 e = {}; 3238   9 e = {};
HITCBC 3239   9 return static_cast<T>(d); 3239   9 return static_cast<T>(d);
3240   } 3240   }
HITCBC 3241   11 e = error::not_exact; 3241   11 e = error::not_exact;
3242   } 3242   }
3243   else 3243   else
3244   { 3244   {
HITCBC 3245   47 e = error::not_number; 3245   47 e = error::not_number;
3246   } 3246   }
HITCBC 3247   80 return T{}; 3247   80 return T{};
3248   } 3248   }
3249   3249  
3250   template<class T> 3250   template<class T>
3251   auto 3251   auto
HITCBC 3252   119 to_number(error& e) const noexcept -> 3252   119 to_number(error& e) const noexcept ->
3253   typename std::enable_if< 3253   typename std::enable_if<
3254   std::is_unsigned<T>::value && 3254   std::is_unsigned<T>::value &&
3255   ! std::is_same<T, bool>::value, 3255   ! std::is_same<T, bool>::value,
3256   T>::type 3256   T>::type
3257   { 3257   {
HITCBC 3258   119 if(sca_.k == json::kind::int64) 3258   119 if(sca_.k == json::kind::int64)
3259   { 3259   {
HITCBC 3260   44 auto const i = sca_.i; 3260   44 auto const i = sca_.i;
HITCBC 3261   72 if( i >= 0 && static_cast<std::uint64_t>(i) <= 3261   72 if( i >= 0 && static_cast<std::uint64_t>(i) <=
HITCBC 3262   28 (std::numeric_limits<T>::max)()) 3262   28 (std::numeric_limits<T>::max)())
3263   { 3263   {
HITCBC 3264   22 e = {}; 3264   22 e = {};
HITCBC 3265   22 return static_cast<T>(i); 3265   22 return static_cast<T>(i);
3266   } 3266   }
HITCBC 3267   22 e = error::not_exact; 3267   22 e = error::not_exact;
3268   } 3268   }
HITCBC 3269   75 else if(sca_.k == json::kind::uint64) 3269   75 else if(sca_.k == json::kind::uint64)
3270   { 3270   {
HITCBC 3271   58 auto const u = sca_.u; 3271   58 auto const u = sca_.u;
HITCBC 3272   58 if(u <= (std::numeric_limits<T>::max)()) 3272   58 if(u <= (std::numeric_limits<T>::max)())
3273   { 3273   {
HITCBC 3274   52 e = {}; 3274   52 e = {};
HITCBC 3275   52 return static_cast<T>(u); 3275   52 return static_cast<T>(u);
3276   } 3276   }
HITCBC 3277   6 e = error::not_exact; 3277   6 e = error::not_exact;
3278   } 3278   }
HITCBC 3279   17 else if(sca_.k == json::kind::double_) 3279   17 else if(sca_.k == json::kind::double_)
3280   { 3280   {
HITCBC 3281   12 auto const d = sca_.d; 3281   12 auto const d = sca_.d;
HITCBC 3282   8 if( d >= 0 && 3282   8 if( d >= 0 &&
HITCBC 3283   20 d <= (detail::to_number_limit<T>::max)() && 3283   20 d <= (detail::to_number_limit<T>::max)() &&
HITCBC 3284   8 static_cast<T>(d) == d) 3284   8 static_cast<T>(d) == d)
3285   { 3285   {
HITCBC 3286   4 e = {}; 3286   4 e = {};
HITCBC 3287   4 return static_cast<T>(d); 3287   4 return static_cast<T>(d);
3288   } 3288   }
HITCBC 3289   8 e = error::not_exact; 3289   8 e = error::not_exact;
3290   } 3290   }
3291   else 3291   else
3292   { 3292   {
HITCBC 3293   5 e = error::not_number; 3293   5 e = error::not_number;
3294   } 3294   }
HITCBC 3295   41 return T{}; 3295   41 return T{};
3296   } 3296   }
3297   3297  
3298   template<class T> 3298   template<class T>
3299   auto 3299   auto
HITCBC 3300   67 to_number(error& e) const noexcept -> 3300   67 to_number(error& e) const noexcept ->
3301   typename std::enable_if< 3301   typename std::enable_if<
3302   std::is_floating_point< 3302   std::is_floating_point<
3303   T>::value, T>::type 3303   T>::value, T>::type
3304   { 3304   {
HITCBC 3305   67 if(sca_.k == json::kind::int64) 3305   67 if(sca_.k == json::kind::int64)
3306   { 3306   {
HITCBC 3307   16 e = {}; 3307   16 e = {};
HITCBC 3308   16 return static_cast<T>(sca_.i); 3308   16 return static_cast<T>(sca_.i);
3309   } 3309   }
HITCBC 3310   51 if(sca_.k == json::kind::uint64) 3310   51 if(sca_.k == json::kind::uint64)
3311   { 3311   {
HITCBC 3312   10 e = {}; 3312   10 e = {};
HITCBC 3313   10 return static_cast<T>(sca_.u); 3313   10 return static_cast<T>(sca_.u);
3314   } 3314   }
HITCBC 3315   41 if(sca_.k == json::kind::double_) 3315   41 if(sca_.k == json::kind::double_)
3316   { 3316   {
HITCBC 3317   27 e = {}; 3317   27 e = {};
HITCBC 3318   27 return static_cast<T>(sca_.d); 3318   27 return static_cast<T>(sca_.d);
3319   } 3319   }
HITCBC 3320   14 e = error::not_number; 3320   14 e = error::not_number;
HITCBC 3321   14 return {}; 3321   14 return {};
3322   } 3322   }
3323   }; 3323   };
3324   3324  
3325   // Make sure things are as big as we think they should be 3325   // Make sure things are as big as we think they should be
3326   #if BOOST_JSON_ARCH == 64 3326   #if BOOST_JSON_ARCH == 64
3327   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 ); 3327   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3328   #elif BOOST_JSON_ARCH == 32 3328   #elif BOOST_JSON_ARCH == 32
3329   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 ); 3329   BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3330   #else 3330   #else
3331   # error Unknown architecture 3331   # error Unknown architecture
3332   #endif 3332   #endif
3333   3333  
3334   //---------------------------------------------------------- 3334   //----------------------------------------------------------
3335   3335  
3336   /** A key/value pair. 3336   /** A key/value pair.
3337   3337  
3338   This is the type of element used by the @ref object container. 3338   This is the type of element used by the @ref object container.
3339   */ 3339   */
3340   class key_value_pair 3340   class key_value_pair
3341   { 3341   {
3342   #ifndef BOOST_JSON_DOCS 3342   #ifndef BOOST_JSON_DOCS
3343   friend struct detail::access; 3343   friend struct detail::access;
3344   using access = detail::access; 3344   using access = detail::access;
3345   #endif 3345   #endif
3346   3346  
3347   BOOST_JSON_DECL 3347   BOOST_JSON_DECL
3348   static char const empty_[1]; 3348   static char const empty_[1];
3349   3349  
3350   inline 3350   inline
3351   key_value_pair( 3351   key_value_pair(
3352   pilfered<json::value> k, 3352   pilfered<json::value> k,
3353   pilfered<json::value> v) noexcept; 3353   pilfered<json::value> v) noexcept;
3354   3354  
3355   public: 3355   public:
3356   /** Assignment 3356   /** Assignment
3357   3357  
3358   This type is not copy or move-assignable. The copy assignment operator 3358   This type is not copy or move-assignable. The copy assignment operator
3359   is deleted. 3359   is deleted.
3360   */ 3360   */
3361   key_value_pair& 3361   key_value_pair&
3362   operator=(key_value_pair const&) = delete; 3362   operator=(key_value_pair const&) = delete;
3363   3363  
3364   /** Destructor. 3364   /** Destructor.
3365   3365  
3366   The value is destroyed and all internally allocated memory is freed. 3366   The value is destroyed and all internally allocated memory is freed.
3367   */ 3367   */
HITCBC 3368   59054 ~key_value_pair() noexcept 3368   59054 ~key_value_pair() noexcept
HITCBC 3369   52301 { 3369   52301 {
HITCBC 3370   59054 auto const& sp = value_.storage(); 3370   59054 auto const& sp = value_.storage();
HITCBC 3371   59054 if(sp.is_not_shared_and_deallocate_is_trivial()) 3371   59054 if(sp.is_not_shared_and_deallocate_is_trivial())
MISUBC 3372   return; 3372   return;
HITCBC 3373   59054 if(key_ == empty_) 3373   59054 if(key_ == empty_)
HITCBC 3374   6753 return; 3374   6753 return;
HITCBC 3375   52301 sp->deallocate(const_cast<char*>(key_), 3375   52301 sp->deallocate(const_cast<char*>(key_),
HITCBC 3376   52301 len_ + 1, alignof(char)); 3376   52301 len_ + 1, alignof(char));
HITCBC 3377   59054 } 3377   59054 }
3378   3378  
3379   /** Constructors. 3379   /** Constructors.
3380   3380  
3381   Construct a key/value pair. 3381   Construct a key/value pair.
3382   3382  
3383   @li **(1)** uses a copy of the characters of `key`, and constructs the 3383   @li **(1)** uses a copy of the characters of `key`, and constructs the
3384   value as if by `value(std::forward<Args>(args)...)`. 3384   value as if by `value(std::forward<Args>(args)...)`.
3385   @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`. 3385   @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
3386   @li **(3)** equivalent to 3386   @li **(3)** equivalent to
3387   `key_value_pair(p.first, std::move(p.second), sp)`. 3387   `key_value_pair(p.first, std::move(p.second), sp)`.
3388   @li **(4)** equivalent to 3388   @li **(4)** equivalent to
3389   `key_value_pair(other.key(), other.value(), sp)`. 3389   `key_value_pair(other.key(), other.value(), sp)`.
3390   @li **(5)** equivalent to 3390   @li **(5)** equivalent to
3391   `key_value_pair(other.key(), other.value(), other.storage())`. 3391   `key_value_pair(other.key(), other.value(), other.storage())`.
3392   @li **(6)** the pair s constructed by acquiring ownership of the 3392   @li **(6)** the pair s constructed by acquiring ownership of the
3393   contents of `other` using move semantics. 3393   contents of `other` using move semantics.
3394   @li **(7)** the pair is constructed by acquiring ownership of the 3394   @li **(7)** the pair is constructed by acquiring ownership of the
3395   contents of `other` using pilfer semantics. This is more efficient 3395   contents of `other` using pilfer semantics. This is more efficient
3396   than move construction, when it is known that the moved-from object 3396   than move construction, when it is known that the moved-from object
3397   will be immediately destroyed afterwards. 3397   will be immediately destroyed afterwards.
3398   3398  
3399   With **(2)**, **(3)**, **(4)** the pair uses the memory resource of 3399   With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
3400   `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of 3400   `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
3401   `other.storage()`. With **(1)** it uses whatever memory resource 3401   `other.storage()`. With **(1)** it uses whatever memory resource
3402   `value(std::forward<Args>(args)...)` would use. In any case the pair 3402   `value(std::forward<Args>(args)...)` would use. In any case the pair
3403   acquires shared ownership of its memory resource 3403   acquires shared ownership of its memory resource
3404   3404  
3405   After **(6)** `other` holds an empty key, and a null value with its 3405   After **(6)** `other` holds an empty key, and a null value with its
3406   current storage pointer. 3406   current storage pointer.
3407   3407  
3408   After **(7)** `other` is not in a usable state and may only be destroyed. 3408   After **(7)** `other` is not in a usable state and may only be destroyed.
3409   3409  
3410   @par Complexity 3410   @par Complexity
3411   Constant. 3411   Constant.
3412   3412  
3413   @par Exception Safety 3413   @par Exception Safety
3414   Strong guarantee. Calls to `memory_resource::allocate` may throw. 3414   Strong guarantee. Calls to `memory_resource::allocate` may throw.
3415   @param key The key string to use. 3415   @param key The key string to use.
3416   @param args Optional arguments forwarded to the @ref value constructor. 3416   @param args Optional arguments forwarded to the @ref value constructor.
3417   3417  
3418   @throw boost::system::system_error The size of the key would exceed 3418   @throw boost::system::system_error The size of the key would exceed
3419   @ref string::max_size. 3419   @ref string::max_size.
3420   3420  
3421   @see @ref pilfer, 3421   @see @ref pilfer,
3422   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html). 3422   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
3423   3423  
3424   @{ 3424   @{
3425   */ 3425   */
3426   template<class... Args> 3426   template<class... Args>
3427   explicit 3427   explicit
HITCBC 3428   7885 key_value_pair( 3428   7885 key_value_pair(
3429   string_view key, 3429   string_view key,
3430   Args&&... args) 3430   Args&&... args)
HITCBC 3431   7886 : value_(std::forward<Args>(args)...) 3431   7886 : value_(std::forward<Args>(args)...)
3432   { 3432   {
HITCBC 3433   7884 if(key.size() > string::max_size()) 3433   7884 if(key.size() > string::max_size())
3434   { 3434   {
3435   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION; 3435   BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
HITCBC 3436   1 detail::throw_system_error( error::key_too_large, &loc ); 3436   1 detail::throw_system_error( error::key_too_large, &loc );
3437   } 3437   }
3438   auto s = reinterpret_cast< 3438   auto s = reinterpret_cast<
HITCBC 3439   7883 char*>(value_.storage()-> 3439   7883 char*>(value_.storage()->
HITCBC 3440   7883 allocate(key.size() + 1, alignof(char))); 3440   7883 allocate(key.size() + 1, alignof(char)));
HITCBC 3441   7577 std::memcpy(s, key.data(), key.size()); 3441   7577 std::memcpy(s, key.data(), key.size());
HITCBC 3442   7577 s[key.size()] = 0; 3442   7577 s[key.size()] = 0;
HITCBC 3443   7577 key_ = s; 3443   7577 key_ = s;
HITCBC 3444   7577 len_ = static_cast< 3444   7577 len_ = static_cast<
HITCBC 3445   7577 std::uint32_t>(key.size()); 3445   7577 std::uint32_t>(key.size());
HITCBC 3446   7884 } 3446   7884 }
3447   3447  
3448   /** Overload 3448   /** Overload
3449   3449  
3450   @param p A `std::pair` with the key string and @ref value to construct 3450   @param p A `std::pair` with the key string and @ref value to construct
3451   with. 3451   with.
3452   @param sp A pointer to the @ref boost::container::pmr::memory_resource 3452   @param sp A pointer to the @ref boost::container::pmr::memory_resource
3453   to use. 3453   to use.
3454   */ 3454   */
3455   explicit 3455   explicit
MISUBC 3456   key_value_pair( 3456   key_value_pair(
3457   std::pair< 3457   std::pair<
3458   string_view, 3458   string_view,
3459   json::value> const& p, 3459   json::value> const& p,
3460   storage_ptr sp = {}) 3460   storage_ptr sp = {})
MISUBC 3461   : key_value_pair( 3461   : key_value_pair(
3462   p.first, 3462   p.first,
MISUBC 3463   p.second, 3463   p.second,
MISUBC 3464   std::move(sp)) 3464   std::move(sp))
3465   { 3465   {
MISUBC 3466   } 3466   }
3467   3467  
3468   /// Overload 3468   /// Overload
3469   explicit 3469   explicit
HITCBC 3470   3125 key_value_pair( 3470   3125 key_value_pair(
3471   std::pair< 3471   std::pair<
3472   string_view, 3472   string_view,
3473   json::value>&& p, 3473   json::value>&& p,
3474   storage_ptr sp = {}) 3474   storage_ptr sp = {})
HITCBC 3475   3125 : key_value_pair( 3475   3125 : key_value_pair(
3476   p.first, 3476   p.first,
HITCBC 3477   3125 std::move(p).second, 3477   3125 std::move(p).second,
HITCBC 3478   6250 std::move(sp)) 3478   6250 std::move(sp))
3479   { 3479   {
HITCBC 3480   2978 } 3480   2978 }
3481   3481  
3482   /** Overload 3482   /** Overload
3483   3483  
3484   @param other Another key/value pair. 3484   @param other Another key/value pair.
3485   @param sp 3485   @param sp
3486   */ 3486   */
3487   BOOST_JSON_DECL 3487   BOOST_JSON_DECL
3488   key_value_pair( 3488   key_value_pair(
3489   key_value_pair const& other, 3489   key_value_pair const& other,
3490   storage_ptr sp); 3490   storage_ptr sp);
3491   3491  
3492   /// Overload 3492   /// Overload
HITCBC 3493   758 key_value_pair( 3493   758 key_value_pair(
3494   key_value_pair const& other) 3494   key_value_pair const& other)
HITCBC 3495   758 : key_value_pair(other, 3495   758 : key_value_pair(other,
HITCBC 3496   758 other.storage()) 3496   758 other.storage())
3497   { 3497   {
HITCBC 3498   758 } 3498   758 }
3499   3499  
3500   /// Overload 3500   /// Overload
HITCBC 3501   1 key_value_pair( 3501   1 key_value_pair(
3502   key_value_pair&& other) noexcept 3502   key_value_pair&& other) noexcept
HITCBC 3503   1 : value_(std::move(other.value_)) 3503   1 : value_(std::move(other.value_))
HITCBC 3504   2 , key_(detail::exchange( 3504   2 , key_(detail::exchange(
HITCBC 3505   1 other.key_, empty_)) 3505   1 other.key_, empty_))
HITCBC 3506   2 , len_(detail::exchange( 3506   2 , len_(detail::exchange(
HITCBC 3507   1 other.len_, 0)) 3507   1 other.len_, 0))
3508   { 3508   {
HITCBC 3509   1 } 3509   1 }
3510   3510  
3511   /// Overload 3511   /// Overload
HITCBC 3512   6752 key_value_pair( 3512   6752 key_value_pair(
3513   pilfered<key_value_pair> other) noexcept 3513   pilfered<key_value_pair> other) noexcept
HITCBC 3514   6752 : value_(pilfer(other.get().value_)) 3514   6752 : value_(pilfer(other.get().value_))
HITCBC 3515   13504 , key_(detail::exchange( 3515   13504 , key_(detail::exchange(
HITCBC 3516   6752 other.get().key_, empty_)) 3516   6752 other.get().key_, empty_))
HITCBC 3517   13504 , len_(detail::exchange( 3517   13504 , len_(detail::exchange(
HITCBC 3518   6752 other.get().len_, 0)) 3518   6752 other.get().len_, 0))
3519   { 3519   {
HITCBC 3520   6752 } 3520   6752 }
3521   /// @} 3521   /// @}
3522   3522  
3523   /** The associated memory resource. 3523   /** The associated memory resource.
3524   3524  
3525   Returns a pointer to the memory resource used to construct the value. 3525   Returns a pointer to the memory resource used to construct the value.
3526   3526  
3527   @par Complexity 3527   @par Complexity
3528   Constant. 3528   Constant.
3529   3529  
3530   @par Exception Safety 3530   @par Exception Safety
3531   No-throw guarantee. 3531   No-throw guarantee.
3532   */ 3532   */
3533   storage_ptr const& 3533   storage_ptr const&
HITCBC 3534   758 storage() const noexcept 3534   758 storage() const noexcept
3535   { 3535   {
HITCBC 3536   758 return value_.storage(); 3536   758 return value_.storage();
3537   } 3537   }
3538   3538  
3539   /** The pair's key. 3539   /** The pair's key.
3540   3540  
3541   After construction, the key may not be modified. 3541   After construction, the key may not be modified.
3542   3542  
3543   @par Complexity 3543   @par Complexity
3544   Constant. 3544   Constant.
3545   3545  
3546   @par Exception Safety 3546   @par Exception Safety
3547   No-throw guarantee. 3547   No-throw guarantee.
3548   */ 3548   */
3549   string_view const 3549   string_view const
HITCBC 3550   143420 key() const noexcept 3550   142956 key() const noexcept
3551   { 3551   {
HITCBC 3552   143420 return { key_, len_ }; 3552   142956 return { key_, len_ };
3553   } 3553   }
3554   3554  
3555   /** The pair's key as a null-terminated string. 3555   /** The pair's key as a null-terminated string.
3556   3556  
3557   @par Complexity 3557   @par Complexity
3558   Constant. 3558   Constant.
3559   3559  
3560   @par Exception Safety 3560   @par Exception Safety
3561   No-throw guarantee. 3561   No-throw guarantee.
3562   */ 3562   */
3563   char const* 3563   char const*
HITCBC 3564   1 key_c_str() const noexcept 3564   1 key_c_str() const noexcept
3565   { 3565   {
HITCBC 3566   1 return key_; 3566   1 return key_;
3567   } 3567   }
3568   3568  
3569   /** The pair's value. 3569   /** The pair's value.
3570   3570  
3571   @par Complexity 3571   @par Complexity
3572   Constant. 3572   Constant.
3573   3573  
3574   @par Exception Safety 3574   @par Exception Safety
3575   No-throw guarantee. 3575   No-throw guarantee.
3576   3576  
3577   @{ 3577   @{
3578   */ 3578   */
3579   json::value const& 3579   json::value const&
HITCBC 3580   65222 value() const& noexcept 3580   65222 value() const& noexcept
3581   { 3581   {
HITCBC 3582   65222 return value_; 3582   65222 return value_;
3583   } 3583   }
3584   3584  
3585   json::value&& 3585   json::value&&
3586   value() && noexcept 3586   value() && noexcept
3587   { 3587   {
3588   return std::move( value() ); 3588   return std::move( value() );
3589   } 3589   }
3590   3590  
3591   json::value& 3591   json::value&
HITCBC 3592   1078 value() & noexcept 3592   1078 value() & noexcept
3593   { 3593   {
HITCBC 3594   1078 return value_; 3594   1078 return value_;
3595   } 3595   }
3596   /// @} 3596   /// @}
3597   3597  
3598   private: 3598   private:
3599   json::value value_; 3599   json::value value_;
3600   char const* key_; 3600   char const* key_;
3601   std::uint32_t len_; 3601   std::uint32_t len_;
3602   std::uint32_t next_; 3602   std::uint32_t next_;
3603   }; 3603   };
3604   3604  
3605   //---------------------------------------------------------- 3605   //----------------------------------------------------------
3606   3606  
3607   #ifdef BOOST_JSON_DOCS 3607   #ifdef BOOST_JSON_DOCS
3608   3608  
3609   /** Tuple-like element access. 3609   /** Tuple-like element access.
3610   3610  
3611   This overload of `get` permits the key and value of a @ref key_value_pair 3611   This overload of `get` permits the key and value of a @ref key_value_pair
3612   to be accessed by index. For example: 3612   to be accessed by index. For example:
3613   3613  
3614   @code 3614   @code
3615   key_value_pair kvp("num", 42); 3615   key_value_pair kvp("num", 42);
3616   string_view key = get<0>(kvp); 3616   string_view key = get<0>(kvp);
3617   value& jv = get<1>(kvp); 3617   value& jv = get<1>(kvp);
3618   @endcode 3618   @endcode
3619   3619  
3620   @par Structured Bindings 3620   @par Structured Bindings
3621   When using C++17 or greater, objects of type @ref key_value_pair may be 3621   When using C++17 or greater, objects of type @ref key_value_pair may be
3622   used to initialize structured bindings: 3622   used to initialize structured bindings:
3623   3623  
3624   @code 3624   @code
3625   key_value_pair kvp("num", 42); 3625   key_value_pair kvp("num", 42);
3626   auto& [key, value] = kvp; 3626   auto& [key, value] = kvp;
3627   @endcode 3627   @endcode
3628   3628  
3629   Depending on the value of `I`, the return type will be: 3629   Depending on the value of `I`, the return type will be:
3630   3630  
3631   @li `string_view const` if `I == 0`, or 3631   @li `string_view const` if `I == 0`, or
3632   @li `value&`, `value const&`, or `value&&` if `I == 1`. 3632   @li `value&`, `value const&`, or `value&&` if `I == 1`.
3633   3633  
3634   Using any other value for `I` is ill-formed. 3634   Using any other value for `I` is ill-formed.
3635   3635  
3636   @par Constraints 3636   @par Constraints
3637   `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >` 3637   `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3638   3638  
3639   @tparam I The element index to access. 3639   @tparam I The element index to access.
3640   3640  
3641   @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`. 3641   @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
3642   3642  
3643   @param kvp The @ref key_value_pair object to access. 3643   @param kvp The @ref key_value_pair object to access.
3644   */ 3644   */
3645   template< 3645   template<
3646   std::size_t I, 3646   std::size_t I,
3647   class T> 3647   class T>
3648   __see_below__ 3648   __see_below__
3649   get(T&& kvp) noexcept; 3649   get(T&& kvp) noexcept;
3650   3650  
3651   #else 3651   #else
3652   3652  
3653   template<std::size_t I> 3653   template<std::size_t I>
3654   auto 3654   auto
3655   get(key_value_pair const&) noexcept -> 3655   get(key_value_pair const&) noexcept ->
3656   typename std::conditional<I == 0, 3656   typename std::conditional<I == 0,
3657   string_view const, 3657   string_view const,
3658   value const&>::type 3658   value const&>::type
3659   { 3659   {
3660   static_assert(I == 0, 3660   static_assert(I == 0,
3661   "key_value_pair index out of range"); 3661   "key_value_pair index out of range");
3662   } 3662   }
3663   3663  
3664   template<std::size_t I> 3664   template<std::size_t I>
3665   auto 3665   auto
3666   get(key_value_pair&) noexcept -> 3666   get(key_value_pair&) noexcept ->
3667   typename std::conditional<I == 0, 3667   typename std::conditional<I == 0,
3668   string_view const, 3668   string_view const,
3669   value&>::type 3669   value&>::type
3670   { 3670   {
3671   static_assert(I == 0, 3671   static_assert(I == 0,
3672   "key_value_pair index out of range"); 3672   "key_value_pair index out of range");
3673   } 3673   }
3674   3674  
3675   template<std::size_t I> 3675   template<std::size_t I>
3676   auto 3676   auto
3677   get(key_value_pair&&) noexcept -> 3677   get(key_value_pair&&) noexcept ->
3678   typename std::conditional<I == 0, 3678   typename std::conditional<I == 0,
3679   string_view const, 3679   string_view const,
3680   value&&>::type 3680   value&&>::type
3681   { 3681   {
3682   static_assert(I == 0, 3682   static_assert(I == 0,
3683   "key_value_pair index out of range"); 3683   "key_value_pair index out of range");
3684   } 3684   }
3685   3685  
3686   /** Extracts a key_value_pair's key using tuple-like interface 3686   /** Extracts a key_value_pair's key using tuple-like interface
3687   */ 3687   */
3688   template<> 3688   template<>
3689   inline 3689   inline
3690   string_view const 3690   string_view const
HITCBC 3691   19609 get<0>(key_value_pair const& kvp) noexcept 3691   19609 get<0>(key_value_pair const& kvp) noexcept
3692   { 3692   {
HITCBC 3693   19609 return kvp.key(); 3693   19609 return kvp.key();
3694   } 3694   }
3695   3695  
3696   /** Extracts a key_value_pair's key using tuple-like interface 3696   /** Extracts a key_value_pair's key using tuple-like interface
3697   */ 3697   */
3698   template<> 3698   template<>
3699   inline 3699   inline
3700   string_view const 3700   string_view const
HITCBC 3701   7 get<0>(key_value_pair& kvp) noexcept 3701   7 get<0>(key_value_pair& kvp) noexcept
3702   { 3702   {
HITCBC 3703   7 return kvp.key(); 3703   7 return kvp.key();
3704   } 3704   }
3705   3705  
3706   /** Extracts a key_value_pair's key using tuple-like interface 3706   /** Extracts a key_value_pair's key using tuple-like interface
3707   */ 3707   */
3708   template<> 3708   template<>
3709   inline 3709   inline
3710   string_view const 3710   string_view const
3711   get<0>(key_value_pair&& kvp) noexcept 3711   get<0>(key_value_pair&& kvp) noexcept
3712   { 3712   {
3713   return kvp.key(); 3713   return kvp.key();
3714   } 3714   }
3715   3715  
3716   /** Extracts a key_value_pair's value using tuple-like interface 3716   /** Extracts a key_value_pair's value using tuple-like interface
3717   */ 3717   */
3718   template<> 3718   template<>
3719   inline 3719   inline
3720   value const& 3720   value const&
HITCBC 3721   28299 get<1>(key_value_pair const& kvp) noexcept 3721   28299 get<1>(key_value_pair const& kvp) noexcept
3722   { 3722   {
HITCBC 3723   28299 return kvp.value(); 3723   28299 return kvp.value();
3724   } 3724   }
3725   3725  
3726   /** Extracts a key_value_pair's value using tuple-like interface 3726   /** Extracts a key_value_pair's value using tuple-like interface
3727   */ 3727   */
3728   template<> 3728   template<>
3729   inline 3729   inline
3730   value& 3730   value&
HITCBC 3731   7 get<1>(key_value_pair& kvp) noexcept 3731   7 get<1>(key_value_pair& kvp) noexcept
3732   { 3732   {
HITCBC 3733   7 return kvp.value(); 3733   7 return kvp.value();
3734   } 3734   }
3735   3735  
3736   /** Extracts a key_value_pair's value using tuple-like interface 3736   /** Extracts a key_value_pair's value using tuple-like interface
3737   */ 3737   */
3738   template<> 3738   template<>
3739   inline 3739   inline
3740   value&& 3740   value&&
3741   get<1>(key_value_pair&& kvp) noexcept 3741   get<1>(key_value_pair&& kvp) noexcept
3742   { 3742   {
3743   return std::move(kvp.value()); 3743   return std::move(kvp.value());
3744   } 3744   }
3745   3745  
3746   #endif 3746   #endif
3747   3747  
3748   } // namespace json 3748   } // namespace json
3749   } // namespace boost 3749   } // namespace boost
3750   3750  
3751   #ifdef __clang__ 3751   #ifdef __clang__
3752   # pragma clang diagnostic push 3752   # pragma clang diagnostic push
3753   # pragma clang diagnostic ignored "-Wmismatched-tags" 3753   # pragma clang diagnostic ignored "-Wmismatched-tags"
3754   #endif 3754   #endif
3755   3755  
3756   #ifndef BOOST_JSON_DOCS 3756   #ifndef BOOST_JSON_DOCS
3757   3757  
3758   namespace std { 3758   namespace std {
3759   3759  
3760   /** Tuple-like size access for key_value_pair 3760   /** Tuple-like size access for key_value_pair
3761   */ 3761   */
3762   template<> 3762   template<>
3763   struct tuple_size< ::boost::json::key_value_pair > 3763   struct tuple_size< ::boost::json::key_value_pair >
3764   : std::integral_constant<std::size_t, 2> 3764   : std::integral_constant<std::size_t, 2>
3765   { 3765   {
3766   }; 3766   };
3767   3767  
3768   /** Tuple-like access for the key type of key_value_pair 3768   /** Tuple-like access for the key type of key_value_pair
3769   */ 3769   */
3770   template<> 3770   template<>
3771   struct tuple_element<0, ::boost::json::key_value_pair> 3771   struct tuple_element<0, ::boost::json::key_value_pair>
3772   { 3772   {
3773   using type = ::boost::json::string_view const; 3773   using type = ::boost::json::string_view const;
3774   }; 3774   };
3775   3775  
3776   /** Tuple-like access for the value type of key_value_pair 3776   /** Tuple-like access for the value type of key_value_pair
3777   */ 3777   */
3778   template<> 3778   template<>
3779   struct tuple_element<1, ::boost::json::key_value_pair> 3779   struct tuple_element<1, ::boost::json::key_value_pair>
3780   { 3780   {
3781   using type = ::boost::json::value&; 3781   using type = ::boost::json::value&;
3782   }; 3782   };
3783   3783  
3784   /** Tuple-like access for the value type of key_value_pair 3784   /** Tuple-like access for the value type of key_value_pair
3785   */ 3785   */
3786   template<> 3786   template<>
3787   struct tuple_element<1, ::boost::json::key_value_pair const> 3787   struct tuple_element<1, ::boost::json::key_value_pair const>
3788   { 3788   {
3789   using type = ::boost::json::value const&; 3789   using type = ::boost::json::value const&;
3790   }; 3790   };
3791   3791  
3792   } // std 3792   } // std
3793   3793  
3794   #endif 3794   #endif
3795   3795  
3796   // std::hash specialization 3796   // std::hash specialization
3797   #ifndef BOOST_JSON_DOCS 3797   #ifndef BOOST_JSON_DOCS
3798   namespace std { 3798   namespace std {
3799   template <> 3799   template <>
3800   struct hash< ::boost::json::value > { 3800   struct hash< ::boost::json::value > {
3801   BOOST_JSON_DECL 3801   BOOST_JSON_DECL
3802   std::size_t 3802   std::size_t
3803   operator()(::boost::json::value const& jv) const noexcept; 3803   operator()(::boost::json::value const& jv) const noexcept;
3804   }; 3804   };
3805   } // std 3805   } // std
3806   #endif 3806   #endif
3807   3807  
3808   3808  
3809   #ifdef __clang__ 3809   #ifdef __clang__
3810   # pragma clang diagnostic pop 3810   # pragma clang diagnostic pop
3811   #endif 3811   #endif
3812   3812  
3813   // These are here because value, array, 3813   // These are here because value, array,
3814   // and object form cyclic references. 3814   // and object form cyclic references.
3815   3815  
3816   #include <boost/json/detail/impl/array.hpp> 3816   #include <boost/json/detail/impl/array.hpp>
3817   #include <boost/json/impl/array.hpp> 3817   #include <boost/json/impl/array.hpp>
3818   #include <boost/json/impl/object.hpp> 3818   #include <boost/json/impl/object.hpp>
3819   #include <boost/json/impl/value.hpp> 3819   #include <boost/json/impl/value.hpp>
3820   3820  
3821   // These must come after array and object 3821   // These must come after array and object
3822   #include <boost/json/impl/value_ref.hpp> 3822   #include <boost/json/impl/value_ref.hpp>
3823   3823  
3824   #endif 3824   #endif