LCOV - code coverage report
Current view: top level - json - value.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 98.9 % 525 519
Test Date: 2025-12-23 17:21:58 Functions: 96.9 % 196 190

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
       4              : //
       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)
       7              : //
       8              : // Official repository: https://github.com/boostorg/json
       9              : //
      10              : 
      11              : #ifndef BOOST_JSON_VALUE_HPP
      12              : #define BOOST_JSON_VALUE_HPP
      13              : 
      14              : #include <boost/json/detail/config.hpp>
      15              : #include <boost/json/array.hpp>
      16              : #include <boost/json/kind.hpp>
      17              : #include <boost/json/object.hpp>
      18              : #include <boost/json/pilfer.hpp>
      19              : #include <boost/json/set_pointer_options.hpp>
      20              : #include <boost/json/storage_ptr.hpp>
      21              : #include <boost/json/string.hpp>
      22              : #include <boost/json/string_view.hpp>
      23              : #include <boost/json/value_ref.hpp>
      24              : #include <boost/json/detail/except.hpp>
      25              : #include <boost/json/detail/value.hpp>
      26              : #include <cstdlib>
      27              : #include <cstring>
      28              : #include <initializer_list>
      29              : #include <iosfwd>
      30              : #include <limits>
      31              : #include <new>
      32              : #include <type_traits>
      33              : #include <utility>
      34              : 
      35              : namespace boost {
      36              : namespace json {
      37              : 
      38              : //----------------------------------------------------------
      39              : 
      40              : /** The type used to represent any JSON value
      41              : 
      42              :     This is a
      43              :     <a href="https://en.cppreference.com/w/cpp/concepts/regular"><em>Regular</em></a>
      44              :     type which works like
      45              :     a variant of the basic JSON data types: array,
      46              :     object, string, number, boolean, and null.
      47              : 
      48              :     @par Thread Safety
      49              : 
      50              :     Distinct instances may be accessed concurrently.
      51              :     Non-const member functions of a shared instance
      52              :     may not be called concurrently with any other
      53              :     member functions of that instance.
      54              : */
      55              : class value
      56              : {
      57              : #ifndef BOOST_JSON_DOCS
      58              :     using scalar = detail::scalar;
      59              : 
      60              :     union
      61              :     {
      62              :         storage_ptr sp_; // must come first
      63              :         array       arr_;
      64              :         object      obj_;
      65              :         string      str_;
      66              :         scalar      sca_;
      67              :     };
      68              : #endif
      69              : 
      70              :     struct init_iter;
      71              : 
      72              : #ifndef BOOST_JSON_DOCS
      73              :     // VFALCO doc toolchain incorrectly treats this as public
      74              :     friend struct detail::access;
      75              : #endif
      76              : 
      77              :     explicit
      78         2120 :     value(
      79              :         detail::unchecked_array&& ua)
      80         2120 :         : arr_(std::move(ua))
      81              :     {
      82         2082 :     }
      83              : 
      84              :     explicit
      85        34879 :     value(
      86              :         detail::unchecked_object&& uo)
      87        34879 :         : obj_(std::move(uo))
      88              :     {
      89        34840 :     }
      90              : 
      91        30296 :     value(
      92              :         detail::key_t const&,
      93              :         string_view s,
      94              :         storage_ptr sp)
      95        30296 :         : str_(detail::key_t{}, s, std::move(sp))
      96              :     {
      97        30236 :     }
      98              : 
      99         8060 :     value(
     100              :         detail::key_t const&,
     101              :         string_view s1,
     102              :         string_view s2,
     103              :         storage_ptr sp)
     104         8060 :         : str_(detail::key_t{}, s1, s2, std::move(sp))
     105              :     {
     106         8060 :     }
     107              : 
     108         6580 :     inline bool is_scalar() const noexcept
     109              :     {
     110         6580 :         return sca_.k < json::kind::string;
     111              :     }
     112              : 
     113              : public:
     114              :     /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
     115              :     using allocator_type = container::pmr::polymorphic_allocator<value>;
     116              : 
     117              :     /** Destructor.
     118              : 
     119              :         The value and all of its contents are destroyed.
     120              :         Any dynamically allocated memory that was allocated
     121              :         internally is freed.
     122              : 
     123              :         @par Complexity
     124              :         Constant, or linear in size for array or object.
     125              : 
     126              :         @par Exception Safety
     127              :         No-throw guarantee.
     128              :     */
     129              :     BOOST_JSON_DECL
     130              :     ~value() noexcept;
     131              : 
     132              :     /** Default constructor.
     133              : 
     134              :         The constructed value is null,
     135              :         using the [default memory resource].
     136              : 
     137              :         @par Complexity
     138              :         Constant.
     139              : 
     140              :         @par Exception Safety
     141              :         No-throw guarantee.
     142              : 
     143              :         [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
     144              :     */
     145          210 :     value() noexcept
     146          210 :         : sca_()
     147              :     {
     148          210 :     }
     149              : 
     150              :     /** Constructor.
     151              : 
     152              :         The constructed value is null, using the
     153              :         specified `boost::container::pmr::memory_resource`.
     154              : 
     155              :         @par Complexity
     156              :         Constant.
     157              : 
     158              :         @par Exception Safety
     159              :         No-throw guarantee.
     160              : 
     161              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     162              :         use. The container will acquire shared ownership of the memory
     163              :         resource.
     164              :     */
     165              :     explicit
     166         7052 :     value(storage_ptr sp) noexcept
     167         7052 :         : sca_(std::move(sp))
     168              :     {
     169         7052 :     }
     170              : 
     171              :     /** Pilfer constructor.
     172              : 
     173              :         The value is constructed by acquiring ownership
     174              :         of the contents of `other` using pilfer semantics.
     175              :         This is more efficient than move construction, when
     176              :         it is known that the moved-from object will be
     177              :         immediately destroyed afterwards.
     178              : 
     179              :         @par Complexity
     180              :         Constant.
     181              : 
     182              :         @par Exception Safety
     183              :         No-throw guarantee.
     184              : 
     185              :         @param other The value to pilfer. After pilfer
     186              :         construction, `other` is not in a usable state
     187              :         and may only be destroyed.
     188              : 
     189              :         @see @ref pilfer,
     190              :             <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
     191              :                 Valueless Variants Considered Harmful</a>
     192              :     */
     193      2129001 :     value(pilfered<value> other) noexcept
     194      2129001 :     {
     195      2129001 :         relocate(this, other.get());
     196      2129001 :         ::new(&other.get().sca_) scalar();
     197      2129001 :     }
     198              : 
     199              :     /** Copy constructor.
     200              : 
     201              :         The value is constructed with a copy of the
     202              :         contents of `other`, using the same
     203              :         memory resource as `other`.
     204              : 
     205              :         @par Complexity
     206              :         Linear in the size of `other`.
     207              : 
     208              :         @par Exception Safety
     209              :         Strong guarantee.
     210              :         Calls to `memory_resource::allocate` may throw.
     211              : 
     212              :         @param other The value to copy.
     213              :     */
     214           19 :     value(value const& other)
     215           19 :         : value(other, other.storage())
     216              :     {
     217           19 :     }
     218              : 
     219              :     /** Copy constructor
     220              : 
     221              :         The value is constructed with a copy of the
     222              :         contents of `other`, using the
     223              :         specified memory resource.
     224              : 
     225              :         @par Complexity
     226              :         Linear in the size of `other`.
     227              : 
     228              :         @par Exception Safety
     229              :         Strong guarantee.
     230              :         Calls to `memory_resource::allocate` may throw.
     231              : 
     232              :         @param other The value to copy.
     233              : 
     234              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     235              :         use. The container will acquire shared ownership of the memory
     236              :         resource.
     237              :     */
     238              :     BOOST_JSON_DECL
     239              :     value(
     240              :         value const& other,
     241              :         storage_ptr sp);
     242              : 
     243              :     /** Move constructor
     244              : 
     245              :         The value is constructed by acquiring ownership of
     246              :         the contents of `other` and shared ownership of
     247              :         `other`'s memory resource.
     248              : 
     249              :         @note
     250              : 
     251              :         After construction, the moved-from value becomes a
     252              :         null value with its current storage pointer.
     253              : 
     254              :         @par Complexity
     255              :         Constant.
     256              : 
     257              :         @par Exception Safety
     258              :         No-throw guarantee.
     259              : 
     260              :         @param other The value to move.
     261              :     */
     262              :     BOOST_JSON_DECL
     263              :     value(value&& other) noexcept;
     264              : 
     265              :     /** Move constructor
     266              : 
     267              :         The value is constructed with the contents of
     268              :         `other` by move semantics, using the specified
     269              :         memory resource:
     270              : 
     271              :         @li If `*other.storage() == *sp`, ownership of
     272              :         the underlying memory is transferred in constant
     273              :         time, with no possibility of exceptions.
     274              :         After construction, the moved-from value becomes
     275              :         a null value with its current storage pointer.
     276              : 
     277              :         @li If `*other.storage() != *sp`, an
     278              :         element-wise copy is performed if
     279              :         `other.is_structured() == true`, which may throw.
     280              :         In this case, the moved-from value is not
     281              :         changed.
     282              : 
     283              :         @par Complexity
     284              :         Constant or linear in the size of `other`.
     285              : 
     286              :         @par Exception Safety
     287              :         Strong guarantee.
     288              :         Calls to `memory_resource::allocate` may throw.
     289              : 
     290              :         @param other The value to move.
     291              : 
     292              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     293              :         use. The container will acquire shared ownership of the memory
     294              :         resource.
     295              :     */
     296              :     BOOST_JSON_DECL
     297              :     value(
     298              :         value&& other,
     299              :         storage_ptr sp);
     300              : 
     301              :     //------------------------------------------------------
     302              :     //
     303              :     // Conversion
     304              :     //
     305              :     //------------------------------------------------------
     306              : 
     307              :     /** Construct a null.
     308              : 
     309              :         A null value is a monostate.
     310              : 
     311              :         @par Complexity
     312              :         Constant.
     313              : 
     314              :         @par Exception Safety
     315              :         No-throw guarantee.
     316              : 
     317              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     318              :         use. The container will acquire shared ownership of the memory
     319              :         resource.
     320              :     */
     321         9563 :     value(
     322              :         std::nullptr_t,
     323              :         storage_ptr sp = {}) noexcept
     324         9563 :         : sca_(std::move(sp))
     325              :     {
     326         9563 :     }
     327              : 
     328              :     /** Construct a bool.
     329              : 
     330              :         This constructs a `bool` value using
     331              :         the specified memory resource.
     332              : 
     333              :         @par Complexity
     334              :         Constant.
     335              : 
     336              :         @par Exception Safety
     337              :         No-throw guarantee.
     338              : 
     339              :         @param b The initial value.
     340              : 
     341              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     342              :         use. The container will acquire shared ownership of the memory
     343              :         resource.
     344              :     */
     345              : #ifdef BOOST_JSON_DOCS
     346              :     value(
     347              :         bool b,
     348              :         storage_ptr sp = {}) noexcept;
     349              : #else
     350              :     template<class T
     351              :         ,class = typename std::enable_if<
     352              :             std::is_same<T, bool>::value>::type
     353              :     >
     354          774 :     value(
     355              :         T b,
     356              :         storage_ptr sp = {}) noexcept
     357          774 :         : sca_(b, std::move(sp))
     358              :     {
     359          774 :     }
     360              : #endif
     361              : 
     362              :     /** Construct a `std::int64_t`.
     363              : 
     364              :         @par Complexity
     365              :         Constant.
     366              : 
     367              :         @par Exception Safety
     368              :         No-throw guarantee.
     369              : 
     370              :         @param i The initial value.
     371              : 
     372              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     373              :         use. The container will acquire shared ownership of the memory
     374              :         resource.
     375              :     */
     376            3 :     value(
     377              :         signed char i,
     378              :         storage_ptr sp = {}) noexcept
     379            3 :         : sca_(static_cast<std::int64_t>(
     380            3 :             i), std::move(sp))
     381              :     {
     382            3 :     }
     383              : 
     384              :     /** Construct a `std::int64_t`.
     385              : 
     386              :         @par Complexity
     387              :         Constant.
     388              : 
     389              :         @par Exception Safety
     390              :         No-throw guarantee.
     391              : 
     392              :         @param i The initial value.
     393              : 
     394              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     395              :         use. The container will acquire shared ownership of the memory
     396              :         resource.
     397              :     */
     398            4 :     value(
     399              :         short i,
     400              :         storage_ptr sp = {}) noexcept
     401            4 :         : sca_(static_cast<std::int64_t>(
     402            4 :             i), std::move(sp))
     403              :     {
     404            4 :     }
     405              : 
     406              :     /** Construct a `std::int64_t`.
     407              : 
     408              :         @par Complexity
     409              :         Constant.
     410              : 
     411              :         @par Exception Safety
     412              :         No-throw guarantee.
     413              : 
     414              :         @param i The initial value.
     415              : 
     416              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     417              :         use. The container will acquire shared ownership of the memory
     418              :         resource.
     419              :     */
     420        11233 :     value(
     421              :         int i,
     422              :         storage_ptr sp = {}) noexcept
     423        11233 :         : sca_(static_cast<std::int64_t>(i),
     424        11233 :             std::move(sp))
     425              :     {
     426        11233 :     }
     427              : 
     428              :     /** Construct a `std::int64_t`.
     429              : 
     430              :         @par Complexity
     431              :         Constant.
     432              : 
     433              :         @par Exception Safety
     434              :         No-throw guarantee.
     435              : 
     436              :         @param i The initial value.
     437              : 
     438              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     439              :         use. The container will acquire shared ownership of the memory
     440              :         resource.
     441              :     */
     442         5834 :     value(
     443              :         long i,
     444              :         storage_ptr sp = {}) noexcept
     445         5834 :         : sca_(static_cast<std::int64_t>(i),
     446         5834 :             std::move(sp))
     447              :     {
     448         5834 :     }
     449              : 
     450              :     /** Construct a `std::int64_t`.
     451              : 
     452              :         @par Complexity
     453              :         Constant.
     454              : 
     455              :         @par Exception Safety
     456              :         No-throw guarantee.
     457              : 
     458              :         @param i The initial value.
     459              : 
     460              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     461              :         use. The container will acquire shared ownership of the memory
     462              :         resource.
     463              :     */
     464            3 :     value(
     465              :         long long i,
     466              :         storage_ptr sp = {}) noexcept
     467            3 :         : sca_(static_cast<std::int64_t>(i),
     468            3 :             std::move(sp))
     469              :     {
     470            3 :     }
     471              : 
     472              :     /** Construct a `std::uint64_t`.
     473              : 
     474              :         @par Complexity
     475              :         Constant.
     476              : 
     477              :         @par Exception Safety
     478              :         No-throw guarantee.
     479              : 
     480              :         @param u The initial value.
     481              : 
     482              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     483              :         use. The container will acquire shared ownership of the memory
     484              :         resource.
     485              :     */
     486           23 :     value(
     487              :         unsigned char u,
     488              :         storage_ptr sp = {}) noexcept
     489           23 :         : sca_(static_cast<std::uint64_t>(
     490           23 :             u), std::move(sp))
     491              :     {
     492           23 :     }
     493              : 
     494              :     /** Construct a `std::uint64_t`.
     495              : 
     496              :         @par Complexity
     497              :         Constant.
     498              : 
     499              :         @par Exception Safety
     500              :         No-throw guarantee.
     501              : 
     502              :         @param u The initial value.
     503              : 
     504              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     505              :         use. The container will acquire shared ownership of the memory
     506              :         resource.
     507              :     */
     508            3 :     value(
     509              :         unsigned short u,
     510              :         storage_ptr sp = {}) noexcept
     511            3 :         : sca_(static_cast<std::uint64_t>(u),
     512            3 :             std::move(sp))
     513              :     {
     514            3 :     }
     515              : 
     516              :     /** Construct a `std::uint64_t`.
     517              : 
     518              :         @par Complexity
     519              :         Constant.
     520              : 
     521              :         @par Exception Safety
     522              :         No-throw guarantee.
     523              : 
     524              :         @param u The initial value.
     525              : 
     526              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     527              :         use. The container will acquire shared ownership of the memory
     528              :         resource.
     529              :     */
     530           52 :     value(
     531              :         unsigned int u,
     532              :         storage_ptr sp = {}) noexcept
     533           52 :         : sca_(static_cast<std::uint64_t>(u),
     534           52 :             std::move(sp))
     535              :     {
     536           52 :     }
     537              : 
     538              :     /** Construct a `std::uint64_t`.
     539              : 
     540              :         @par Complexity
     541              :         Constant.
     542              : 
     543              :         @par Exception Safety
     544              :         No-throw guarantee.
     545              : 
     546              :         @param u The initial value.
     547              : 
     548              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     549              :         use. The container will acquire shared ownership of the memory
     550              :         resource.
     551              :     */
     552          215 :     value(
     553              :         unsigned long u,
     554              :         storage_ptr sp = {}) noexcept
     555          215 :         : sca_(static_cast<std::uint64_t>(u),
     556          215 :             std::move(sp))
     557              :     {
     558          215 :     }
     559              : 
     560              :     /** Construct a `std::uint64_t`.
     561              : 
     562              :         @par Complexity
     563              :         Constant.
     564              : 
     565              :         @par Exception Safety
     566              :         No-throw guarantee.
     567              : 
     568              :         @param u The initial value.
     569              : 
     570              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     571              :         use. The container will acquire shared ownership of the memory
     572              :         resource.
     573              :     */
     574            2 :     value(
     575              :         unsigned long long u,
     576              :         storage_ptr sp = {}) noexcept
     577            2 :         : sca_(static_cast<std::uint64_t>(u),
     578            2 :             std::move(sp))
     579              :     {
     580            2 :     }
     581              : 
     582              :     /** Construct a `double`.
     583              : 
     584              :         @par Complexity
     585              :         Constant.
     586              : 
     587              :         @par Exception Safety
     588              :         No-throw guarantee.
     589              : 
     590              :         @param d The initial value.
     591              : 
     592              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     593              :         use. The container will acquire shared ownership of the memory
     594              :         resource.
     595              :     */
     596      2039949 :     value(
     597              :         double d,
     598              :         storage_ptr sp = {}) noexcept
     599      2039949 :         : sca_(d, std::move(sp))
     600              :     {
     601      2039949 :     }
     602              : 
     603              :     /** Construct a @ref string.
     604              : 
     605              :         The string is constructed with a copy of the
     606              :         string view `s`, using the specified memory resource.
     607              : 
     608              :         @par Complexity
     609              :         Linear in `s.size()`.
     610              : 
     611              :         @par Exception Safety
     612              :         Strong guarantee.
     613              :         Calls to `memory_resource::allocate` may throw.
     614              : 
     615              :         @param s The string view to construct with.
     616              : 
     617              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     618              :         use. The container will acquire shared ownership of the memory
     619              :         resource.
     620              :     */
     621        17178 :     value(
     622              :         string_view s,
     623              :         storage_ptr sp = {})
     624        17178 :         : str_(s, std::move(sp))
     625              :     {
     626        17170 :     }
     627              : 
     628              :     /** Construct a @ref string.
     629              : 
     630              :         The string is constructed with a copy of the
     631              :         null-terminated string `s`, using the specified
     632              :         memory resource.
     633              : 
     634              :         @par Complexity
     635              :         Linear in `std::strlen(s)`.
     636              : 
     637              :         @par Exception Safety
     638              :         Strong guarantee.
     639              :         Calls to `memory_resource::allocate` may throw.
     640              : 
     641              :         @param s The null-terminated string to construct
     642              :         with.
     643              : 
     644              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     645              :         use. The container will acquire shared ownership of the memory
     646              :         resource.
     647              :     */
     648          134 :     value(
     649              :         char const* s,
     650              :         storage_ptr sp = {})
     651          134 :         : str_(s, std::move(sp))
     652              :     {
     653          134 :     }
     654              : 
     655              :     /** Construct a @ref string.
     656              : 
     657              :         The value is constructed from `other`, using the
     658              :         same memory resource. To transfer ownership, use `std::move`:
     659              : 
     660              :         @par Example
     661              :         @code
     662              :         string str = "The Boost C++ Library Collection";
     663              : 
     664              :         // transfer ownership
     665              :         value jv( std::move(str) );
     666              : 
     667              :         assert( str.empty() );
     668              :         assert( *str.storage() == *jv.storage() );
     669              :         @endcode
     670              : 
     671              :         @par Complexity
     672              :         Constant.
     673              : 
     674              :         @par Exception Safety
     675              :         No-throw guarantee.
     676              : 
     677              :         @param other The string to construct with.
     678              :     */
     679          399 :     value(
     680              :         string other) noexcept
     681          399 :         : str_(std::move(other))
     682              :     {
     683          399 :     }
     684              : 
     685              :     /** Construct a @ref string.
     686              : 
     687              :         The value is copy constructed from `other`,
     688              :         using the specified memory resource.
     689              : 
     690              :         @par Complexity
     691              :         Linear in `other.size()`.
     692              : 
     693              :         @par Exception Safety
     694              :         Strong guarantee.
     695              :         Calls to `memory_resource::allocate` may throw.
     696              : 
     697              :         @param other The string to construct with.
     698              : 
     699              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     700              :         use. The container will acquire shared ownership of the memory
     701              :         resource.
     702              :     */
     703           12 :     value(
     704              :         string const& other,
     705              :         storage_ptr sp)
     706           12 :         : str_(
     707              :             other,
     708           12 :             std::move(sp))
     709              :     {
     710           12 :     }
     711              : 
     712              :     /** Construct a @ref string.
     713              : 
     714              :         The value is move constructed from `other`,
     715              :         using the specified memory resource.
     716              : 
     717              :         @par Complexity
     718              :         Constant or linear in `other.size()`.
     719              : 
     720              :         @par Exception Safety
     721              :         Strong guarantee.
     722              :         Calls to `memory_resource::allocate` may throw.
     723              : 
     724              :         @param other The string to construct with.
     725              : 
     726              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     727              :         use. The container will acquire shared ownership of the memory
     728              :         resource.
     729              :     */
     730            9 :     value(
     731              :         string&& other,
     732              :         storage_ptr sp)
     733           18 :         : str_(
     734            9 :             std::move(other),
     735            9 :             std::move(sp))
     736              :     {
     737            9 :     }
     738              : 
     739              :     /** Construct a @ref string.
     740              : 
     741              :         This is the fastest way to construct
     742              :         an empty string, using the specified
     743              :         memory resource. The variable @ref string_kind
     744              :         may be passed as the first parameter
     745              :         to select this overload:
     746              : 
     747              :         @par Example
     748              :         @code
     749              :         // Construct an empty string
     750              : 
     751              :         value jv( string_kind );
     752              :         @endcode
     753              : 
     754              :         @par Complexity
     755              :         Constant.
     756              : 
     757              :         @par Exception Safety
     758              :         No-throw guarantee.
     759              : 
     760              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     761              :         use. The container will acquire shared ownership of the memory
     762              :         resource.
     763              : 
     764              :         @see @ref string_kind
     765              :     */
     766         8977 :     value(
     767              :         string_kind_t,
     768              :         storage_ptr sp = {}) noexcept
     769         8977 :         : str_(std::move(sp))
     770              :     {
     771         8977 :     }
     772              : 
     773              :     /** Construct an @ref array.
     774              : 
     775              :         The value is constructed from `other`, using the
     776              :         same memory resource. To transfer ownership, use `std::move`:
     777              : 
     778              :         @par Example
     779              :         @code
     780              :         array arr( {1, 2, 3, 4, 5} );
     781              : 
     782              :         // transfer ownership
     783              :         value jv( std::move(arr) );
     784              : 
     785              :         assert( arr.empty() );
     786              :         assert( *arr.storage() == *jv.storage() );
     787              :         @endcode
     788              : 
     789              :         @par Complexity
     790              :         Constant.
     791              : 
     792              :         @par Exception Safety
     793              :         No-throw guarantee.
     794              : 
     795              :         @param other The array to construct with.
     796              :     */
     797          180 :     value(array other) noexcept
     798          180 :         : arr_(std::move(other))
     799              :     {
     800          180 :     }
     801              : 
     802              :     /** Construct an @ref array.
     803              : 
     804              :         The value is copy constructed from `other`,
     805              :         using the specified memory resource.
     806              : 
     807              :         @par Complexity
     808              :         Linear in `other.size()`.
     809              : 
     810              :         @par Exception Safety
     811              :         Strong guarantee.
     812              :         Calls to `memory_resource::allocate` may throw.
     813              : 
     814              :         @param other The array to construct with.
     815              : 
     816              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     817              :         use. The container will acquire shared ownership of the memory
     818              :         resource.
     819              :     */
     820            4 :     value(
     821              :         array const& other,
     822              :         storage_ptr sp)
     823            4 :         : arr_(
     824              :             other,
     825            4 :             std::move(sp))
     826              :     {
     827            4 :     }
     828              : 
     829              :     /** Construct an @ref array.
     830              : 
     831              :         The value is move-constructed from `other`,
     832              :         using the specified memory resource.
     833              : 
     834              :         @par Complexity
     835              :         Constant or linear in `other.size()`.
     836              : 
     837              :         @par Exception Safety
     838              :         Strong guarantee.
     839              :         Calls to `memory_resource::allocate` may throw.
     840              : 
     841              :         @param other The array to construct with.
     842              : 
     843              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     844              :         use. The container will acquire shared ownership of the memory
     845              :         resource.
     846              :     */
     847           22 :     value(
     848              :         array&& other,
     849              :         storage_ptr sp)
     850           44 :         : arr_(
     851           22 :             std::move(other),
     852           22 :             std::move(sp))
     853              :     {
     854           22 :     }
     855              : 
     856              :     /** Construct an @ref array.
     857              : 
     858              :         This is the fastest way to construct
     859              :         an empty array, using the specified
     860              :         memory resource. The variable @ref array_kind
     861              :         may be passed as the first parameter
     862              :         to select this overload:
     863              : 
     864              :         @par Example
     865              :         @code
     866              :         // Construct an empty array
     867              : 
     868              :         value jv( array_kind );
     869              :         @endcode
     870              : 
     871              :         @par Complexity
     872              :         Constant.
     873              : 
     874              :         @par Exception Safety
     875              :         No-throw guarantee.
     876              : 
     877              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     878              :         use. The container will acquire shared ownership of the memory
     879              :         resource.
     880              : 
     881              :         @see @ref array_kind
     882              :     */
     883           17 :     value(
     884              :         array_kind_t,
     885              :         storage_ptr sp = {}) noexcept
     886           17 :         : arr_(std::move(sp))
     887              :     {
     888           17 :     }
     889              : 
     890              :     /** Construct an @ref object.
     891              : 
     892              :         The value is constructed from `other`, using the
     893              :         same memory resource. To transfer ownership, use `std::move`:
     894              : 
     895              :         @par Example
     896              :         @code
     897              :         object obj( {{"a",1}, {"b",2}, {"c"},3}} );
     898              : 
     899              :         // transfer ownership
     900              :         value jv( std::move(obj) );
     901              : 
     902              :         assert( obj.empty() );
     903              :         assert( *obj.storage() == *jv.storage() );
     904              :         @endcode
     905              : 
     906              :         @par Complexity
     907              :         Constant.
     908              : 
     909              :         @par Exception Safety
     910              :         No-throw guarantee.
     911              : 
     912              :         @param other The object to construct with.
     913              :     */
     914           61 :     value(object other) noexcept
     915           61 :         : obj_(std::move(other))
     916              :     {
     917           61 :     }
     918              : 
     919              :     /** Construct an @ref object.
     920              : 
     921              :         The value is copy constructed from `other`,
     922              :         using the specified memory resource.
     923              : 
     924              :         @par Complexity
     925              :         Linear in `other.size()`.
     926              : 
     927              :         @par Exception Safety
     928              :         Strong guarantee.
     929              :         Calls to `memory_resource::allocate` may throw.
     930              : 
     931              :         @param other The object to construct with.
     932              : 
     933              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     934              :         use. The container will acquire shared ownership of the memory
     935              :         resource.
     936              :     */
     937            4 :     value(
     938              :         object const& other,
     939              :         storage_ptr sp)
     940            4 :         : obj_(
     941              :             other,
     942            4 :             std::move(sp))
     943              :     {
     944            4 :     }
     945              : 
     946              :     /** Construct an @ref object.
     947              : 
     948              :         The value is move constructed from `other`,
     949              :         using the specified memory resource.
     950              : 
     951              :         @par Complexity
     952              :         Constant or linear in `other.size()`.
     953              : 
     954              :         @par Exception Safety
     955              :         Strong guarantee.
     956              :         Calls to `memory_resource::allocate` may throw.
     957              : 
     958              :         @param other The object to construct with.
     959              : 
     960              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     961              :         use. The container will acquire shared ownership of the memory
     962              :         resource.
     963              :     */
     964           57 :     value(
     965              :         object&& other,
     966              :         storage_ptr sp)
     967          114 :         : obj_(
     968           57 :             std::move(other),
     969           57 :             std::move(sp))
     970              :     {
     971           57 :     }
     972              : 
     973              :     /** Construct an @ref object.
     974              : 
     975              :         This is the fastest way to construct
     976              :         an empty object, using the specified
     977              :         memory resource. The variable @ref object_kind
     978              :         may be passed as the first parameter
     979              :         to select this overload:
     980              : 
     981              :         @par Example
     982              :         @code
     983              :         // Construct an empty object
     984              : 
     985              :         value jv( object_kind );
     986              :         @endcode
     987              : 
     988              :         @par Complexity
     989              :         Constant.
     990              : 
     991              :         @par Exception Safety
     992              :         No-throw guarantee.
     993              : 
     994              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
     995              :         use. The container will acquire shared ownership of the memory
     996              :         resource.
     997              : 
     998              :         @see @ref object_kind
     999              :     */
    1000           18 :     value(
    1001              :         object_kind_t,
    1002              :         storage_ptr sp = {}) noexcept
    1003           18 :         : obj_(std::move(sp))
    1004              :     {
    1005           18 :     }
    1006              : 
    1007              :     /** Construct from an initializer-list
    1008              : 
    1009              :         @li If the initializer list consists of key/value
    1010              :         pairs, an @ref object is created; otherwise,
    1011              : 
    1012              :         @li if the size of the initializer list is exactly 1, the object is
    1013              :         constructed directly from that sole element; otherwise,
    1014              : 
    1015              :         @li an @ref array is created.
    1016              : 
    1017              :         The contents of the initializer list are copied to the newly
    1018              :         constructed value using the specified memory resource.
    1019              : 
    1020              :         @par Complexity
    1021              :         Linear in `init.size()`.
    1022              : 
    1023              :         @par Exception Safety
    1024              :         Strong guarantee.
    1025              :         Calls to `memory_resource::allocate` may throw.
    1026              : 
    1027              :         @param init The initializer list to construct from.
    1028              : 
    1029              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
    1030              :         use. The container will acquire shared ownership of the memory
    1031              :         resource.
    1032              : 
    1033              :         @par Note
    1034              :         The previous behavior of this constructor was to always
    1035              :         construct either an @ref object or an @ref array. In practice though,
    1036              :         several C++ implementations did not treat `value{x}` as a constructor
    1037              :         from initializer list. This effectively resulted in different behavior
    1038              :         on different implementations. <br>
    1039              : 
    1040              :         If you need the legacy behavior define macro
    1041              :         `BOOST_JSON_LEGACY_INIT_LIST_BEHAVIOR` when you are building the
    1042              :         library. The macro and the functionality will be deprecated in the
    1043              :         future and then removed, so we urge you to change your code for the new
    1044              :         behavior as soon as possible. The simplest way to create an @ref array
    1045              :         with 1 element using an initializer list is via `array{x}`.
    1046              :     */
    1047              :     BOOST_JSON_DECL
    1048              :     value(
    1049              :         std::initializer_list<value_ref> init,
    1050              :         storage_ptr sp = {});
    1051              : 
    1052              :     //------------------------------------------------------
    1053              :     //
    1054              :     // Assignment
    1055              :     //
    1056              :     //------------------------------------------------------
    1057              : 
    1058              :     /** Copy assignment.
    1059              : 
    1060              :         The contents of the value are replaced with an
    1061              :         element-wise copy of the contents of `other`.
    1062              : 
    1063              :         @par Complexity
    1064              :         Linear in the size of `*this` plus `other`.
    1065              : 
    1066              :         @par Exception Safety
    1067              :         Strong guarantee.
    1068              :         Calls to `memory_resource::allocate` may throw.
    1069              : 
    1070              :         @param other The value to copy.
    1071              :     */
    1072              :     BOOST_JSON_DECL
    1073              :     value&
    1074              :     operator=(value const& other);
    1075              : 
    1076              :     /** Move assignment.
    1077              : 
    1078              :         The contents of the value are replaced with the
    1079              :         contents of `other` using move semantics:
    1080              : 
    1081              :         @li If `*other.storage() == *sp`, ownership of
    1082              :         the underlying memory is transferred in constant
    1083              :         time, with no possibility of exceptions.
    1084              :         After assignment, the moved-from value becomes
    1085              :         a null with its current storage pointer.
    1086              : 
    1087              :         @li If `*other.storage() != *sp`, an
    1088              :         element-wise copy is performed if
    1089              :         `other.is_structured() == true`, which may throw.
    1090              :         In this case, the moved-from value is not
    1091              :         changed.
    1092              : 
    1093              :         @par Complexity
    1094              :         Constant, or linear in
    1095              :         `this->size()` plus `other.size()`.
    1096              : 
    1097              :         @par Exception Safety
    1098              :         Strong guarantee.
    1099              :         Calls to `memory_resource::allocate` may throw.
    1100              : 
    1101              :         @param other The value to assign from.
    1102              :     */
    1103              :     BOOST_JSON_DECL
    1104              :     value&
    1105              :     operator=(value&& other);
    1106              : 
    1107              :     /** Assignment.
    1108              : 
    1109              :         Replace `*this` with the value formed by
    1110              :         constructing from `init` and `this->storage()`.
    1111              :         If the initializer list consists of key/value
    1112              :         pairs, the resulting @ref object is assigned.
    1113              :         Otherwise an @ref array is assigned. The contents
    1114              :         of the initializer list are moved to `*this`
    1115              :         using the existing memory resource.
    1116              : 
    1117              :         @par Complexity
    1118              :         Linear in `init.size()`.
    1119              : 
    1120              :         @par Exception Safety
    1121              :         Strong guarantee.
    1122              :         Calls to `memory_resource::allocate` may throw.
    1123              : 
    1124              :         @param init The initializer list to assign from.
    1125              :     */
    1126              :     BOOST_JSON_DECL
    1127              :     value&
    1128              :     operator=(
    1129              :         std::initializer_list<value_ref> init);
    1130              : 
    1131              :     /** Assignment.
    1132              : 
    1133              :         Replace `*this` with null.
    1134              : 
    1135              :         @par Exception Safety
    1136              :         No-throw guarantee.
    1137              : 
    1138              :         @par Complexity
    1139              :         Linear in the size of `*this`.
    1140              :     */
    1141              :     value&
    1142           18 :     operator=(std::nullptr_t) noexcept
    1143              :     {
    1144           18 :         if(is_scalar())
    1145              :         {
    1146           12 :             sca_.k = json::kind::null;
    1147              :         }
    1148              :         else
    1149              :         {
    1150           18 :             ::new(&sca_) scalar(
    1151            6 :                 destroy());
    1152              :         }
    1153           18 :         return *this;
    1154              :     }
    1155              : 
    1156              :     /** Assignment.
    1157              : 
    1158              :         Replace `*this` with `b`.
    1159              : 
    1160              :         @par Exception Safety
    1161              :         No-throw guarantee.
    1162              : 
    1163              :         @par Complexity
    1164              :         Linear in the size of `*this`.
    1165              : 
    1166              :         @param b The new value.
    1167              :     */
    1168              : #ifdef BOOST_JSON_DOCS
    1169              :     value& operator=(bool b) noexcept;
    1170              : #else
    1171              :     template<class T
    1172              :         ,class = typename std::enable_if<
    1173              :             std::is_same<T, bool>::value>::type
    1174              :     >
    1175           51 :     value& operator=(T b) noexcept
    1176              :     {
    1177           51 :         if(is_scalar())
    1178              :         {
    1179           50 :             sca_.b = b;
    1180           50 :             sca_.k = json::kind::bool_;
    1181              :         }
    1182              :         else
    1183              :         {
    1184            1 :             ::new(&sca_) scalar(
    1185              :                 b, destroy());
    1186              :         }
    1187           51 :         return *this;
    1188              :     }
    1189              : #endif
    1190              : 
    1191              :     /** Assignment.
    1192              : 
    1193              :         Replace `*this` with `i`.
    1194              : 
    1195              :         @par Exception Safety
    1196              :         No-throw guarantee.
    1197              : 
    1198              :         @par Complexity
    1199              :         Linear in the size of `*this`.
    1200              : 
    1201              :         @param i The new value.
    1202              :     */
    1203              :     /** @{ */
    1204            2 :     value& operator=(signed char i) noexcept
    1205              :     {
    1206            2 :         return operator=(
    1207            2 :             static_cast<long long>(i));
    1208              :     }
    1209              : 
    1210            8 :     value& operator=(short i) noexcept
    1211              :     {
    1212            8 :         return operator=(
    1213            8 :             static_cast<long long>(i));
    1214              :     }
    1215              : 
    1216         6402 :     value& operator=(int i) noexcept
    1217              :     {
    1218         6402 :         return operator=(
    1219         6402 :             static_cast<long long>(i));
    1220              :     }
    1221              : 
    1222           12 :     value& operator=(long i) noexcept
    1223              :     {
    1224           12 :         return operator=(
    1225           12 :             static_cast<long long>(i));
    1226              :     }
    1227              : 
    1228         6432 :     value& operator=(long long i) noexcept
    1229              :     {
    1230         6432 :         if(is_scalar())
    1231              :         {
    1232         6429 :             sca_.i = i;
    1233         6429 :             sca_.k = json::kind::int64;
    1234              :         }
    1235              :         else
    1236              :         {
    1237            9 :             ::new(&sca_) scalar(static_cast<
    1238            3 :                 std::int64_t>(i), destroy());
    1239              :         }
    1240         6432 :         return *this;
    1241              :     }
    1242              :     /** @} */
    1243              : 
    1244              :     /** Assignment.
    1245              : 
    1246              :         Replace `*this` with `i`.
    1247              : 
    1248              :         @par Exception Safety
    1249              :         No-throw guarantee.
    1250              : 
    1251              :         @par Complexity
    1252              :         Linear in the size of `*this`.
    1253              : 
    1254              :         @param u The new value.
    1255              :     */
    1256              :     /** @{ */
    1257            6 :     value& operator=(unsigned char u) noexcept
    1258              :     {
    1259            6 :         return operator=(static_cast<
    1260            6 :             unsigned long long>(u));
    1261              :     }
    1262              : 
    1263            8 :     value& operator=(unsigned short u) noexcept
    1264              :     {
    1265            8 :         return operator=(static_cast<
    1266            8 :             unsigned long long>(u));
    1267              :     }
    1268              : 
    1269            8 :     value& operator=(unsigned int u) noexcept
    1270              :     {
    1271            8 :         return operator=(static_cast<
    1272            8 :             unsigned long long>(u));
    1273              :     }
    1274              : 
    1275           17 :     value& operator=(unsigned long u) noexcept
    1276              :     {
    1277           17 :         return operator=(static_cast<
    1278           17 :             unsigned long long>(u));
    1279              :     }
    1280              : 
    1281           47 :     value& operator=(unsigned long long u) noexcept
    1282              :     {
    1283           47 :         if(is_scalar())
    1284              :         {
    1285           46 :             sca_.u = u;
    1286           46 :             sca_.k = json::kind::uint64;
    1287              :         }
    1288              :         else
    1289              :         {
    1290            3 :             ::new(&sca_) scalar(static_cast<
    1291            1 :                 std::uint64_t>(u), destroy());
    1292              :         }
    1293           47 :         return *this;
    1294              :     }
    1295              :     /** @} */
    1296              : 
    1297              :     /** Assignment.
    1298              : 
    1299              :         Replace `*this` with `d`.
    1300              : 
    1301              :         @par Exception Safety
    1302              :         No-throw guarantee.
    1303              : 
    1304              :         @par Complexity
    1305              :         Linear in the size of `*this`.
    1306              : 
    1307              :         @param d The new value.
    1308              :     */
    1309           32 :     value& operator=(double d) noexcept
    1310              :     {
    1311           32 :         if(is_scalar())
    1312              :         {
    1313           25 :             sca_.d = d;
    1314           25 :             sca_.k = json::kind::double_;
    1315              :         }
    1316              :         else
    1317              :         {
    1318           21 :             ::new(&sca_) scalar(
    1319            7 :                 d, destroy());
    1320              :         }
    1321           32 :         return *this;
    1322              :     }
    1323              : 
    1324              :     /** Assignment.
    1325              : 
    1326              :         Replace `*this` with a copy of the string `s`.
    1327              : 
    1328              :         @par Exception Safety
    1329              :         Strong guarantee.
    1330              :         Calls to `memory_resource::allocate` may throw.
    1331              : 
    1332              :         @par Complexity
    1333              :         Linear in the sum of sizes of `*this` and `s`
    1334              : 
    1335              :         @param s The new string.
    1336              :     */
    1337              :     /** @{ */
    1338              :     BOOST_JSON_DECL value& operator=(string_view s);
    1339              :     BOOST_JSON_DECL value& operator=(char const* s);
    1340              :     BOOST_JSON_DECL value& operator=(string const& s);
    1341              :     /** @} */
    1342              : 
    1343              :     /** Assignment.
    1344              : 
    1345              :         The contents of the value are replaced with the
    1346              :         contents of `s` using move semantics:
    1347              : 
    1348              :         @li If `*other.storage() == *this->storage()`,
    1349              :         ownership of the underlying memory is transferred
    1350              :         in constant time, with no possibility of exceptions.
    1351              :         After assignment, the moved-from string becomes
    1352              :         empty with its current storage pointer.
    1353              : 
    1354              :         @li If `*other.storage() != *this->storage()`, an
    1355              :         element-wise copy is performed, which may throw.
    1356              :         In this case, the moved-from string is not
    1357              :         changed.
    1358              : 
    1359              :         @par Complexity
    1360              :         Constant, or linear in the size of `*this` plus `s.size()`.
    1361              : 
    1362              :         @par Exception Safety
    1363              :         Strong guarantee.
    1364              :         Calls to `memory_resource::allocate` may throw.
    1365              : 
    1366              :         @param s The string to move-assign from.
    1367              :     */
    1368              :     BOOST_JSON_DECL value& operator=(string&& s);
    1369              : 
    1370              :     /** Assignment.
    1371              : 
    1372              :         Replace `*this` with a copy of the array `arr`.
    1373              : 
    1374              :         @par Exception Safety
    1375              :         Strong guarantee.
    1376              :         Calls to `memory_resource::allocate` may throw.
    1377              : 
    1378              :         @par Complexity
    1379              :         Linear in the sum of sizes of `*this` and `arr`
    1380              : 
    1381              :         @param arr The new array.
    1382              :     */
    1383              :     BOOST_JSON_DECL value& operator=(array const& arr);
    1384              : 
    1385              :     /** Assignment.
    1386              : 
    1387              :         The contents of the value are replaced with the
    1388              :         contents of `arr` using move semantics:
    1389              : 
    1390              :         @li If `*arr.storage() == *this->storage()`,
    1391              :         ownership of the underlying memory is transferred
    1392              :         in constant time, with no possibility of exceptions.
    1393              :         After assignment, the moved-from array becomes
    1394              :         empty with its current storage pointer.
    1395              : 
    1396              :         @li If `*arr.storage() != *this->storage()`, an
    1397              :         element-wise copy is performed, which may throw.
    1398              :         In this case, the moved-from array is not
    1399              :         changed.
    1400              : 
    1401              :         @par Complexity
    1402              :         Constant, or linear in the size of `*this` plus `arr.size()`.
    1403              : 
    1404              :         @par Exception Safety
    1405              :         Strong guarantee.
    1406              :         Calls to `memory_resource::allocate` may throw.
    1407              : 
    1408              :         @param arr The array to move-assign from.
    1409              :     */
    1410              :     BOOST_JSON_DECL value& operator=(array&& arr);
    1411              : 
    1412              :     /** Assignment.
    1413              : 
    1414              :         Replace `*this` with a copy of the obect `obj`.
    1415              : 
    1416              :         @par Exception Safety
    1417              :         Strong guarantee.
    1418              :         Calls to `memory_resource::allocate` may throw.
    1419              : 
    1420              :         @par Complexity
    1421              :         Linear in the sum of sizes of `*this` and `obj`
    1422              : 
    1423              :         @param obj The new object.
    1424              :     */
    1425              :     BOOST_JSON_DECL value& operator=(object const& obj);
    1426              : 
    1427              :     /** Assignment.
    1428              : 
    1429              :         The contents of the value are replaced with the
    1430              :         contents of `obj` using move semantics:
    1431              : 
    1432              :         @li If `*obj.storage() == *this->storage()`,
    1433              :         ownership of the underlying memory is transferred
    1434              :         in constant time, with no possibility of exceptions.
    1435              :         After assignment, the moved-from object becomes
    1436              :         empty with its current storage pointer.
    1437              : 
    1438              :         @li If `*obj.storage() != *this->storage()`, an
    1439              :         element-wise copy is performed, which may throw.
    1440              :         In this case, the moved-from object is not
    1441              :         changed.
    1442              : 
    1443              :         @par Complexity
    1444              :         Constant, or linear in the size of `*this` plus `obj.size()`.
    1445              : 
    1446              :         @par Exception Safety
    1447              :         Strong guarantee.
    1448              :         Calls to `memory_resource::allocate` may throw.
    1449              : 
    1450              :         @param obj The object to move-assign from.
    1451              :     */
    1452              :     BOOST_JSON_DECL value& operator=(object&& obj);
    1453              : 
    1454              :     //------------------------------------------------------
    1455              :     //
    1456              :     // Modifiers
    1457              :     //
    1458              :     //------------------------------------------------------
    1459              : 
    1460              :     /** Change the kind to null, discarding the previous contents.
    1461              : 
    1462              :         The value is replaced with a null,
    1463              :         destroying the previous contents.
    1464              : 
    1465              :         @par Complexity
    1466              :         Linear in the size of `*this`.
    1467              : 
    1468              :         @par Exception Safety
    1469              :         No-throw guarantee.
    1470              :     */
    1471              :     void
    1472            8 :     emplace_null() noexcept
    1473              :     {
    1474            8 :         *this = nullptr;
    1475            8 :     }
    1476              : 
    1477              :     /** Return a reference to a `bool`, changing the kind and replacing the contents.
    1478              : 
    1479              :         The value is replaced with a `bool`
    1480              :         initialized to `false`, destroying the
    1481              :         previous contents.
    1482              : 
    1483              :         @par Complexity
    1484              :         Linear in the size of `*this`.
    1485              : 
    1486              :         @par Exception Safety
    1487              :         No-throw guarantee.
    1488              :     */
    1489              :     bool&
    1490            1 :     emplace_bool() noexcept
    1491              :     {
    1492            1 :         *this = false;
    1493            1 :         return sca_.b;
    1494              :     }
    1495              : 
    1496              :     /** Return a reference to a `std::int64_t`, changing the kind and replacing the contents.
    1497              : 
    1498              :         The value is replaced with a `std::int64_t`
    1499              :         initialized to zero, destroying the
    1500              :         previous contents.
    1501              : 
    1502              :         @par Complexity
    1503              :         Linear in the size of `*this`.
    1504              : 
    1505              :         @par Exception Safety
    1506              :         No-throw guarantee.
    1507              :     */
    1508              :     std::int64_t&
    1509            2 :     emplace_int64() noexcept
    1510              :     {
    1511            2 :         *this = std::int64_t{};
    1512            2 :         return sca_.i;
    1513              :     }
    1514              : 
    1515              :     /** Return a reference to a `std::uint64_t`, changing the kind and replacing the contents.
    1516              : 
    1517              :         The value is replaced with a `std::uint64_t`
    1518              :         initialized to zero, destroying the
    1519              :         previous contents.
    1520              : 
    1521              :         @par Complexity
    1522              :         Linear in the size of `*this`.
    1523              : 
    1524              :         @par Exception Safety
    1525              :         No-throw guarantee.
    1526              :     */
    1527              :     std::uint64_t&
    1528            1 :     emplace_uint64() noexcept
    1529              :     {
    1530            1 :         *this = std::uint64_t{};
    1531            1 :         return sca_.u;
    1532              :     }
    1533              : 
    1534              :     /** Return a reference to a `double`, changing the kind and replacing the contents.
    1535              : 
    1536              :         The value is replaced with a `double`
    1537              :         initialized to zero, destroying the
    1538              :         previous contents.
    1539              : 
    1540              :         @par Complexity
    1541              :         Linear in the size of `*this`.
    1542              : 
    1543              :         @par Exception Safety
    1544              :         No-throw guarantee.
    1545              :     */
    1546              :     double&
    1547            1 :     emplace_double() noexcept
    1548              :     {
    1549            1 :         *this = double{};
    1550            1 :         return sca_.d;
    1551              :     }
    1552              : 
    1553              :     /** Return a reference to a @ref string, changing the kind and replacing the contents.
    1554              : 
    1555              :         The value is replaced with an empty @ref string
    1556              :         using the current memory resource, destroying the
    1557              :         previous contents.
    1558              : 
    1559              :         @par Complexity
    1560              :         Linear in the size of `*this`.
    1561              : 
    1562              :         @par Exception Safety
    1563              :         No-throw guarantee.
    1564              :     */
    1565              :     BOOST_JSON_DECL
    1566              :     string&
    1567              :     emplace_string() noexcept;
    1568              : 
    1569              :     /** Return a reference to an @ref array, changing the kind and replacing the contents.
    1570              : 
    1571              :         The value is replaced with an empty @ref array
    1572              :         using the current memory resource, destroying the
    1573              :         previous contents.
    1574              : 
    1575              :         @par Complexity
    1576              :         Linear in the size of `*this`.
    1577              : 
    1578              :         @par Exception Safety
    1579              :         No-throw guarantee.
    1580              :     */
    1581              :     BOOST_JSON_DECL
    1582              :     array&
    1583              :     emplace_array() noexcept;
    1584              : 
    1585              :     /** Return a reference to an @ref object, changing the kind and replacing the contents.
    1586              : 
    1587              :         The contents are replaced with an empty @ref object using the current
    1588              :         `boost::container::pmr::memory_resource`. All previously obtained
    1589              :         iterators and references obtained beforehand are invalidated.
    1590              : 
    1591              :         @par Complexity
    1592              :         Linear in the size of `*this`.
    1593              : 
    1594              :         @par Exception Safety
    1595              :         No-throw guarantee.
    1596              :     */
    1597              :     BOOST_JSON_DECL
    1598              :     object&
    1599              :     emplace_object() noexcept;
    1600              : 
    1601              :     /** Swap the given values.
    1602              : 
    1603              :         Exchanges the contents of this value with another value. Ownership of
    1604              :         the respective `boost::container::pmr::memory_resource` objects is not
    1605              :         transferred:
    1606              : 
    1607              :         @li If `*other.storage() == *this->storage()`,
    1608              :         ownership of the underlying memory is swapped in
    1609              :         constant time, with no possibility of exceptions.
    1610              :         All iterators and references remain valid.
    1611              : 
    1612              :         @li If `*other.storage() != *this->storage()`,
    1613              :         the contents are logically swapped by making copies,
    1614              :         which can throw. In this case all iterators and
    1615              :         references are invalidated.
    1616              : 
    1617              :         @par Complexity
    1618              :         Constant or linear in the sum of the sizes of
    1619              :         the values.
    1620              : 
    1621              :         @par Exception Safety
    1622              :         Strong guarantee.
    1623              :         Calls to `memory_resource::allocate` may throw.
    1624              : 
    1625              :         @param other The value to swap with.
    1626              :         If `this == &other`, this function call has no effect.
    1627              :     */
    1628              :     BOOST_JSON_DECL
    1629              :     void
    1630              :     swap(value& other);
    1631              : 
    1632              :     /** Swap the given values.
    1633              : 
    1634              :         Exchanges the contents of value `lhs` with another value `rhs`.
    1635              :         Ownership of the respective `boost::container::pmr::memory_resource`
    1636              :         objects is not transferred.
    1637              : 
    1638              :         @li If `*lhs.storage() == *rhs.storage()`,
    1639              :         ownership of the underlying memory is swapped in
    1640              :         constant time, with no possibility of exceptions.
    1641              :         All iterators and references remain valid.
    1642              : 
    1643              :         @li If `*lhs.storage() != *rhs.storage`,
    1644              :         the contents are logically swapped by a copy,
    1645              :         which can throw. In this case all iterators and
    1646              :         references are invalidated.
    1647              : 
    1648              :         @par Effects
    1649              :         @code
    1650              :         lhs.swap( rhs );
    1651              :         @endcode
    1652              : 
    1653              :         @par Complexity
    1654              :         Constant or linear in the sum of the sizes of
    1655              :         the values.
    1656              : 
    1657              :         @par Exception Safety
    1658              :         Strong guarantee.
    1659              :         Calls to `memory_resource::allocate` may throw.
    1660              : 
    1661              :         @param lhs The value to exchange.
    1662              : 
    1663              :         @param rhs The value to exchange.
    1664              :         If `&lhs == &rhs`, this function call has no effect.
    1665              : 
    1666              :         @see @ref value::swap
    1667              :     */
    1668              :     friend
    1669              :     void
    1670            3 :     swap(value& lhs, value& rhs)
    1671              :     {
    1672            3 :         lhs.swap(rhs);
    1673            3 :     }
    1674              : 
    1675              :     //------------------------------------------------------
    1676              :     //
    1677              :     // Observers
    1678              :     //
    1679              :     //------------------------------------------------------
    1680              : 
    1681              :     /** Returns the kind of this JSON value.
    1682              : 
    1683              :         This function returns the discriminating
    1684              :         enumeration constant of type @ref json::kind
    1685              :         corresponding to the underlying representation
    1686              :         stored in the container.
    1687              : 
    1688              :         @par Complexity
    1689              :         Constant.
    1690              : 
    1691              :         @par Exception Safety
    1692              :         No-throw guarantee.
    1693              :     */
    1694              :     json::kind
    1695      4611906 :     kind() const noexcept
    1696              :     {
    1697              :         return static_cast<json::kind>(
    1698              :             static_cast<unsigned char>(
    1699      4611906 :                 sca_.k) & 0x3f);
    1700              :     }
    1701              : 
    1702              :     /** Return `true` if this is an array
    1703              : 
    1704              :         This function is used to determine if the underlying
    1705              :         representation is a certain kind.
    1706              : 
    1707              :         @par Effects
    1708              :         @code
    1709              :         return this->kind() == kind::array;
    1710              :         @endcode
    1711              : 
    1712              :         @par Complexity
    1713              :         Constant.
    1714              : 
    1715              :         @par Exception Safety
    1716              :         No-throw guarantee.
    1717              :     */
    1718              :     bool
    1719         5896 :     is_array() const noexcept
    1720              :     {
    1721         5896 :         return kind() == json::kind::array;
    1722              :     }
    1723              : 
    1724              :     /** Return `true` if this is an object
    1725              : 
    1726              :         This function is used to determine if the underlying
    1727              :         representation is a certain kind.
    1728              : 
    1729              :         @par Effects
    1730              :         @code
    1731              :         return this->kind() == kind::object;
    1732              :         @endcode
    1733              : 
    1734              :         @par Complexity
    1735              :         Constant.
    1736              : 
    1737              :         @par Exception Safety
    1738              :         No-throw guarantee.
    1739              :     */
    1740              :     bool
    1741        53226 :     is_object() const noexcept
    1742              :     {
    1743        53226 :         return kind() == json::kind::object;
    1744              :     }
    1745              : 
    1746              :     /** Return `true` if this is a string
    1747              : 
    1748              :         This function is used to determine if the underlying
    1749              :         representation is a certain kind.
    1750              : 
    1751              :         @par Effects
    1752              :         @code
    1753              :         return this->kind() == kind::string;
    1754              :         @endcode
    1755              : 
    1756              :         @par Complexity
    1757              :         Constant.
    1758              : 
    1759              :         @par Exception Safety
    1760              :         No-throw guarantee.
    1761              :     */
    1762              :     bool
    1763        88179 :     is_string() const noexcept
    1764              :     {
    1765        88179 :         return kind() == json::kind::string;
    1766              :     }
    1767              : 
    1768              :     /** Return `true` if this is a signed integer
    1769              : 
    1770              :         This function is used to determine if the underlying
    1771              :         representation is a certain kind.
    1772              : 
    1773              :         @par Effects
    1774              :         @code
    1775              :         return this->kind() == kind::int64;
    1776              :         @endcode
    1777              : 
    1778              :         @par Complexity
    1779              :         Constant.
    1780              : 
    1781              :         @par Exception Safety
    1782              :         No-throw guarantee.
    1783              :     */
    1784              :     bool
    1785        14779 :     is_int64() const noexcept
    1786              :     {
    1787        14779 :         return kind() == json::kind::int64;
    1788              :     }
    1789              : 
    1790              :     /** Return `true` if this is a unsigned integer
    1791              : 
    1792              :         This function is used to determine if the underlying
    1793              :         representation is a certain kind.
    1794              : 
    1795              :         @par Effects
    1796              :         @code
    1797              :         return this->kind() == kind::uint64;
    1798              :         @endcode
    1799              : 
    1800              :         @par Complexity
    1801              :         Constant.
    1802              : 
    1803              :         @par Exception Safety
    1804              :         No-throw guarantee.
    1805              :     */
    1806              :     bool
    1807          337 :     is_uint64() const noexcept
    1808              :     {
    1809          337 :         return kind() == json::kind::uint64;
    1810              :     }
    1811              : 
    1812              :     /** Return `true` if this is a double
    1813              : 
    1814              :         This function is used to determine if the underlying
    1815              :         representation is a certain kind.
    1816              : 
    1817              :         @par Effects
    1818              :         @code
    1819              :         return this->kind() == kind::double_;
    1820              :         @endcode
    1821              : 
    1822              :         @par Complexity
    1823              :         Constant.
    1824              : 
    1825              :         @par Exception Safety
    1826              :         No-throw guarantee.
    1827              :     */
    1828              :     bool
    1829      2078641 :     is_double() const noexcept
    1830              :     {
    1831      2078641 :         return kind() == json::kind::double_;
    1832              :     }
    1833              : 
    1834              :     /** Return `true` if this is a bool
    1835              : 
    1836              :         This function is used to determine if the underlying
    1837              :         representation is a certain kind.
    1838              : 
    1839              :         @par Effects
    1840              :         @code
    1841              :         return this->kind() == kind::bool_;
    1842              :         @endcode
    1843              : 
    1844              :         @par Complexity
    1845              :         Constant.
    1846              : 
    1847              :         @par Exception Safety
    1848              :         No-throw guarantee.
    1849              :     */
    1850              :     bool
    1851          944 :     is_bool() const noexcept
    1852              :     {
    1853          944 :         return kind() == json::kind::bool_;
    1854              :     }
    1855              : 
    1856              :     /** Returns true if this is a null.
    1857              : 
    1858              :         This function is used to determine if the underlying
    1859              :         representation is a certain kind.
    1860              : 
    1861              :         @par Effects
    1862              :         @code
    1863              :         return this->kind() == kind::null;
    1864              :         @endcode
    1865              : 
    1866              :         @par Complexity
    1867              :         Constant.
    1868              : 
    1869              :         @par Exception Safety
    1870              :         No-throw guarantee.
    1871              :     */
    1872              :     bool
    1873          140 :     is_null() const noexcept
    1874              :     {
    1875          140 :         return kind() == json::kind::null;
    1876              :     }
    1877              : 
    1878              :     /** Returns true if this is an array or object.
    1879              : 
    1880              :         This function returns `true` if
    1881              :         @ref kind() is either `kind::object` or
    1882              :         `kind::array`.
    1883              : 
    1884              :         @par Complexity
    1885              :         Constant.
    1886              : 
    1887              :         @par Exception Safety
    1888              :         No-throw guarantee.
    1889              :     */
    1890              :     bool
    1891            8 :     is_structured() const noexcept
    1892              :     {
    1893              :         // VFALCO Could use bit 0x20 for this
    1894              :         return
    1895           15 :            kind() == json::kind::object ||
    1896           15 :            kind() == json::kind::array;
    1897              :     }
    1898              : 
    1899              :     /** Returns true if this is not an array or object.
    1900              : 
    1901              :         This function returns `true` if
    1902              :         @ref kind() is neither `kind::object` nor
    1903              :         `kind::array`.
    1904              : 
    1905              :         @par Complexity
    1906              :         Constant.
    1907              : 
    1908              :         @par Exception Safety
    1909              :         No-throw guarantee.
    1910              :     */
    1911              :     bool
    1912            8 :     is_primitive() const noexcept
    1913              :     {
    1914              :         // VFALCO Could use bit 0x20 for this
    1915              :         return
    1916           15 :            sca_.k != json::kind::object &&
    1917           15 :            sca_.k != json::kind::array;
    1918              :     }
    1919              : 
    1920              :     /** Returns true if this is a number.
    1921              : 
    1922              :         This function returns `true` when
    1923              :         @ref kind() is one of the following values:
    1924              :         `kind::int64`, `kind::uint64`, or
    1925              :         `kind::double_`.
    1926              : 
    1927              :         @par Complexity
    1928              :         Constant.
    1929              : 
    1930              :         @par Exception Safety
    1931              :         No-throw guarantee.
    1932              :     */
    1933              :     bool
    1934           83 :     is_number() const noexcept
    1935              :     {
    1936              :         // VFALCO Could use bit 0x40 for this
    1937              :         return
    1938           92 :             kind() == json::kind::int64 ||
    1939           92 :             kind() == json::kind::uint64 ||
    1940           91 :             kind() == json::kind::double_;
    1941              :     }
    1942              : 
    1943              :     //------------------------------------------------------
    1944              : 
    1945              :     /** Return an @ref array pointer if this is an array, else return `nullptr`
    1946              : 
    1947              :         If `this->kind() == kind::array`, returns a pointer
    1948              :         to the underlying array. Otherwise, returns `nullptr`.
    1949              : 
    1950              :         @par Example
    1951              :         The return value is used in both a boolean context and
    1952              :         to assign a variable:
    1953              :         @code
    1954              :         if( auto p = jv.if_array() )
    1955              :             return *p;
    1956              :         @endcode
    1957              : 
    1958              :         @par Complexity
    1959              :         Constant.
    1960              : 
    1961              :         @par Exception Safety
    1962              :         No-throw guarantee.
    1963              :     */
    1964              :     array const*
    1965          196 :     if_array() const noexcept
    1966              :     {
    1967          196 :         if(kind() == json::kind::array)
    1968          159 :             return &arr_;
    1969           37 :         return nullptr;
    1970              :     }
    1971              : 
    1972              :     /** Return an @ref array pointer if this is an array, else return `nullptr`
    1973              : 
    1974              :         If `this->kind() == kind::array`, returns a pointer
    1975              :         to the underlying array. Otherwise, returns `nullptr`.
    1976              : 
    1977              :         @par Example
    1978              :         The return value is used in both a boolean context and
    1979              :         to assign a variable:
    1980              :         @code
    1981              :         if( auto p = jv.if_array() )
    1982              :             return *p;
    1983              :         @endcode
    1984              : 
    1985              :         @par Complexity
    1986              :         Constant.
    1987              : 
    1988              :         @par Exception Safety
    1989              :         No-throw guarantee.
    1990              :     */
    1991              :     array*
    1992            9 :     if_array() noexcept
    1993              :     {
    1994            9 :         if(kind() == json::kind::array)
    1995            2 :             return &arr_;
    1996            7 :         return nullptr;
    1997              :     }
    1998              : 
    1999              :     /** Return an @ref object pointer if this is an object, else return `nullptr`
    2000              : 
    2001              :         If `this->kind() == kind::object`, returns a pointer
    2002              :         to the underlying object. Otherwise, returns `nullptr`.
    2003              : 
    2004              :         @par Example
    2005              :         The return value is used in both a boolean context and
    2006              :         to assign a variable:
    2007              :         @code
    2008              :         if( auto p = jv.if_object() )
    2009              :             return *p;
    2010              :         @endcode
    2011              : 
    2012              :         @par Complexity
    2013              :         Constant.
    2014              : 
    2015              :         @par Exception Safety
    2016              :         No-throw guarantee.
    2017              :     */
    2018              :     object const*
    2019           74 :     if_object() const noexcept
    2020              :     {
    2021           74 :         if(kind() == json::kind::object)
    2022           49 :             return &obj_;
    2023           25 :         return nullptr;
    2024              :     }
    2025              : 
    2026              :     /** Return an @ref object pointer if this is an object, else return `nullptr`
    2027              : 
    2028              :         If `this->kind() == kind::object`, returns a pointer
    2029              :         to the underlying object. Otherwise, returns `nullptr`.
    2030              : 
    2031              :         @par Example
    2032              :         The return value is used in both a boolean context and
    2033              :         to assign a variable:
    2034              :         @code
    2035              :         if( auto p = jv.if_object() )
    2036              :             return *p;
    2037              :         @endcode
    2038              : 
    2039              :         @par Complexity
    2040              :         Constant.
    2041              : 
    2042              :         @par Exception Safety
    2043              :         No-throw guarantee.
    2044              :     */
    2045              :     object*
    2046           10 :     if_object() noexcept
    2047              :     {
    2048           10 :         if(kind() == json::kind::object)
    2049            3 :             return &obj_;
    2050            7 :         return nullptr;
    2051              :     }
    2052              : 
    2053              :     /** Return a @ref string pointer if this is a string, else return `nullptr`
    2054              : 
    2055              :         If `this->kind() == kind::string`, returns a pointer
    2056              :         to the underlying object. Otherwise, returns `nullptr`.
    2057              : 
    2058              :         @par Example
    2059              :         The return value is used in both a boolean context and
    2060              :         to assign a variable:
    2061              :         @code
    2062              :         if( auto p = jv.if_string() )
    2063              :             return *p;
    2064              :         @endcode
    2065              : 
    2066              :         @par Complexity
    2067              :         Constant.
    2068              : 
    2069              :         @par Exception Safety
    2070              :         No-throw guarantee.
    2071              :     */
    2072              :     string const*
    2073          239 :     if_string() const noexcept
    2074              :     {
    2075          239 :         if(kind() == json::kind::string)
    2076          171 :             return &str_;
    2077           68 :         return nullptr;
    2078              :     }
    2079              : 
    2080              :     /** Return a @ref string pointer if this is a string, else return `nullptr`
    2081              : 
    2082              :         If `this->kind() == kind::string`, returns a pointer
    2083              :         to the underlying object. Otherwise, returns `nullptr`.
    2084              : 
    2085              :         @par Example
    2086              :         The return value is used in both a boolean context and
    2087              :         to assign a variable:
    2088              :         @code
    2089              :         if( auto p = jv.if_string() )
    2090              :             return *p;
    2091              :         @endcode
    2092              : 
    2093              :         @par Complexity
    2094              :         Constant.
    2095              : 
    2096              :         @par Exception Safety
    2097              :         No-throw guarantee.
    2098              :     */
    2099              :     string*
    2100           10 :     if_string() noexcept
    2101              :     {
    2102           10 :         if(kind() == json::kind::string)
    2103            3 :             return &str_;
    2104            7 :         return nullptr;
    2105              :     }
    2106              : 
    2107              :     /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
    2108              : 
    2109              :         If `this->kind() == kind::int64`, returns a pointer
    2110              :         to the underlying integer. Otherwise, returns `nullptr`.
    2111              : 
    2112              :         @par Example
    2113              :         The return value is used in both a boolean context and
    2114              :         to assign a variable:
    2115              :         @code
    2116              :         if( auto p = jv.if_int64() )
    2117              :             return *p;
    2118              :         @endcode
    2119              : 
    2120              :         @par Complexity
    2121              :         Constant.
    2122              : 
    2123              :         @par Exception Safety
    2124              :         No-throw guarantee.
    2125              :     */
    2126              :     std::int64_t const*
    2127            8 :     if_int64() const noexcept
    2128              :     {
    2129            8 :         if(kind() == json::kind::int64)
    2130            1 :             return &sca_.i;
    2131            7 :         return nullptr;
    2132              :     }
    2133              : 
    2134              :     /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
    2135              : 
    2136              :         If `this->kind() == kind::int64`, returns a pointer
    2137              :         to the underlying integer. Otherwise, returns `nullptr`.
    2138              : 
    2139              :         @par Example
    2140              :         The return value is used in both a boolean context and
    2141              :         to assign a variable:
    2142              :         @code
    2143              :         if( auto p = jv.if_int64() )
    2144              :             return *p;
    2145              :         @endcode
    2146              : 
    2147              :         @par Complexity
    2148              :         Constant.
    2149              : 
    2150              :         @par Exception Safety
    2151              :         No-throw guarantee.
    2152              :     */
    2153              :     std::int64_t*
    2154           10 :     if_int64() noexcept
    2155              :     {
    2156           10 :         if(kind() == json::kind::int64)
    2157            3 :             return &sca_.i;
    2158            7 :         return nullptr;
    2159              :     }
    2160              : 
    2161              :     /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
    2162              : 
    2163              :         If `this->kind() == kind::uint64`, returns a pointer
    2164              :         to the underlying unsigned integer. Otherwise, returns
    2165              :         `nullptr`.
    2166              : 
    2167              :         @par Example
    2168              :         The return value is used in both a boolean context and
    2169              :         to assign a variable:
    2170              :         @code
    2171              :         if( auto p = jv.if_uint64() )
    2172              :             return *p;
    2173              :         @endcode
    2174              : 
    2175              :         @par Complexity
    2176              :         Constant.
    2177              : 
    2178              :         @par Exception Safety
    2179              :         No-throw guarantee.
    2180              :     */
    2181              :     std::uint64_t const*
    2182            8 :     if_uint64() const noexcept
    2183              :     {
    2184            8 :         if(kind() == json::kind::uint64)
    2185            1 :             return &sca_.u;
    2186            7 :         return nullptr;
    2187              :     }
    2188              : 
    2189              :     /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
    2190              : 
    2191              :         If `this->kind() == kind::uint64`, returns a pointer
    2192              :         to the underlying unsigned integer. Otherwise, returns
    2193              :         `nullptr`.
    2194              : 
    2195              :         @par Example
    2196              :         The return value is used in both a boolean context and
    2197              :         to assign a variable:
    2198              :         @code
    2199              :         if( auto p = jv.if_uint64() )
    2200              :             return *p;
    2201              :         @endcode
    2202              : 
    2203              :         @par Complexity
    2204              :         Constant.
    2205              : 
    2206              :         @par Exception Safety
    2207              :         No-throw guarantee.
    2208              :     */
    2209              :     std::uint64_t*
    2210            8 :     if_uint64() noexcept
    2211              :     {
    2212            8 :         if(kind() == json::kind::uint64)
    2213            1 :             return &sca_.u;
    2214            7 :         return nullptr;
    2215              :     }
    2216              : 
    2217              :     /** Return a `double` pointer if this is a double, else return `nullptr`
    2218              : 
    2219              :         If `this->kind() == kind::double_`, returns a pointer
    2220              :         to the underlying double. Otherwise, returns
    2221              :         `nullptr`.
    2222              : 
    2223              :         @par Example
    2224              :         The return value is used in both a boolean context and
    2225              :         to assign a variable:
    2226              :         @code
    2227              :         if( auto p = jv.if_double() )
    2228              :             return *p;
    2229              :         @endcode
    2230              : 
    2231              :         @par Complexity
    2232              :         Constant.
    2233              : 
    2234              :         @par Exception Safety
    2235              :         No-throw guarantee.
    2236              :     */
    2237              :     double const*
    2238            8 :     if_double() const noexcept
    2239              :     {
    2240            8 :         if(kind() == json::kind::double_)
    2241            1 :             return &sca_.d;
    2242            7 :         return nullptr;
    2243              :     }
    2244              : 
    2245              :     /** Return a `double` pointer if this is a double, else return `nullptr`
    2246              : 
    2247              :         If `this->kind() == kind::double_`, returns a pointer
    2248              :         to the underlying double. Otherwise, returns
    2249              :         `nullptr`.
    2250              : 
    2251              :         @par Example
    2252              :         The return value is used in both a boolean context and
    2253              :         to assign a variable:
    2254              :         @code
    2255              :         if( auto p = jv.if_double() )
    2256              :             return *p;
    2257              :         @endcode
    2258              : 
    2259              :         @par Complexity
    2260              :         Constant.
    2261              : 
    2262              :         @par Exception Safety
    2263              :         No-throw guarantee.
    2264              :     */
    2265              :     double*
    2266            8 :     if_double() noexcept
    2267              :     {
    2268            8 :         if(kind() == json::kind::double_)
    2269            1 :             return &sca_.d;
    2270            7 :         return nullptr;
    2271              :     }
    2272              : 
    2273              :     /** Return a `bool` pointer if this is a boolean, else return `nullptr`
    2274              : 
    2275              :         If `this->kind() == kind::bool_`, returns a pointer
    2276              :         to the underlying boolean. Otherwise, returns
    2277              :         `nullptr`.
    2278              : 
    2279              :         @par Example
    2280              :         The return value is used in both a boolean context and
    2281              :         to assign a variable:
    2282              :         @code
    2283              :         if( auto p = jv.if_bool() )
    2284              :             return *p;
    2285              :         @endcode
    2286              : 
    2287              :         @par Complexity
    2288              :         Constant.
    2289              : 
    2290              :         @par Exception Safety
    2291              :         No-throw guarantee.
    2292              :     */
    2293              :     bool const*
    2294           50 :     if_bool() const noexcept
    2295              :     {
    2296           50 :         if(kind() == json::kind::bool_)
    2297           37 :             return &sca_.b;
    2298           13 :         return nullptr;
    2299              :     }
    2300              : 
    2301              :     /** Return a `bool` pointer if this is a boolean, else return `nullptr`
    2302              : 
    2303              :         If `this->kind() == kind::bool_`, returns a pointer
    2304              :         to the underlying boolean. Otherwise, returns
    2305              :         `nullptr`.
    2306              : 
    2307              :         @par Example
    2308              :         The return value is used in both a boolean context and
    2309              :         to assign a variable:
    2310              :         @code
    2311              :         if( auto p = jv.if_bool() )
    2312              :             return *p;
    2313              :         @endcode
    2314              : 
    2315              :         @par Complexity
    2316              :         Constant.
    2317              : 
    2318              :         @par Exception Safety
    2319              :         No-throw guarantee.
    2320              :     */
    2321              :     bool*
    2322            8 :     if_bool() noexcept
    2323              :     {
    2324            8 :         if(kind() == json::kind::bool_)
    2325            1 :             return &sca_.b;
    2326            7 :         return nullptr;
    2327              :     }
    2328              : 
    2329              :     //------------------------------------------------------
    2330              : 
    2331              :     /** Return the stored number cast to an arithmetic type.
    2332              : 
    2333              :         This function attempts to return the stored value
    2334              :         converted to the arithmetic type `T` which may not
    2335              :         be `bool`:
    2336              : 
    2337              :         @li If `T` is an integral type and the stored
    2338              :         value is a number which can be losslessly converted,
    2339              :         the conversion is performed without error and the
    2340              :         converted number is returned.
    2341              : 
    2342              :         @li If `T` is an integral type and the stored value
    2343              :         is a number which cannot be losslessly converted,
    2344              :         then the operation fails with an error.
    2345              : 
    2346              :         @li If `T` is a floating point type and the stored
    2347              :         value is a number, the conversion is performed
    2348              :         without error. The converted number is returned,
    2349              :         with a possible loss of precision.
    2350              : 
    2351              :         @li Otherwise, if the stored value is not a number;
    2352              :         that is, if `this->is_number()` returns `false`, then
    2353              :         the operation fails with an error.
    2354              : 
    2355              :         @par Constraints
    2356              :         @code
    2357              :         std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
    2358              :         @endcode
    2359              : 
    2360              :         @par Complexity
    2361              :         Constant.
    2362              : 
    2363              :         @par Exception Safety
    2364              :         No-throw guarantee.
    2365              : 
    2366              :         @return The converted number.
    2367              : 
    2368              :         @param ec Set to the error, if any occurred.
    2369              :     */
    2370              : /** @{ */
    2371              :     template<class T>
    2372              : #ifdef BOOST_JSON_DOCS
    2373              :     T
    2374              : #else
    2375              :     typename std::enable_if<
    2376              :         std::is_arithmetic<T>::value &&
    2377              :         ! std::is_same<T, bool>::value,
    2378              :             T>::type
    2379              : #endif
    2380         3478 :     to_number(system::error_code& ec) const noexcept
    2381              :     {
    2382              :         error e;
    2383         3478 :         auto result = to_number<T>(e);
    2384         3478 :         BOOST_JSON_FAIL(ec, e);
    2385         3478 :         return result;
    2386              :     }
    2387              : 
    2388              :     template<class T>
    2389              : #ifdef BOOST_JSON_DOCS
    2390              :     T
    2391              : #else
    2392              :     typename std::enable_if<
    2393              :         std::is_arithmetic<T>::value &&
    2394              :         ! std::is_same<T, bool>::value,
    2395              :             T>::type
    2396              : #endif
    2397            1 :     to_number(std::error_code& ec) const noexcept
    2398              :     {
    2399            1 :         system::error_code jec;
    2400            1 :         auto result = to_number<T>(jec);
    2401            1 :         ec = jec;
    2402            1 :         return result;
    2403              :     }
    2404              : /** @} */
    2405              : 
    2406              :     /** Return the stored number as `boost::system::result<T>`.
    2407              : 
    2408              :         This function attempts to return the stored value converted to the
    2409              :         arithmetic type `T` which may not be `bool`:
    2410              : 
    2411              :         @li If `T` is an integral type and the stored value is a number which
    2412              :             can be losslessly converted, the conversion is performed without
    2413              :             error and `result<T>` containing the converted number is returned.
    2414              : 
    2415              :         @li If `T` is an integral type and the stored value is a number which
    2416              :             cannot be losslessly converted, then `result<T>` containing the
    2417              :             corresponding `error_code` is returned.
    2418              : 
    2419              :         @li If `T` is a floating point type and the stored value is a number,
    2420              :             the conversion is performed without error. `result<T>` containing
    2421              :             the converted number, with a possible loss of precision, is
    2422              :             returned.
    2423              : 
    2424              :         @li Otherwise, if the stored value is not a number; that is, if
    2425              :             `this->is_number()` returns `false`, then `result<T>` containing
    2426              :             the corresponding `error_code` is returned.
    2427              : 
    2428              :         @par Constraints
    2429              :         @code
    2430              :         std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
    2431              :         @endcode
    2432              : 
    2433              :         @par Complexity
    2434              :         Constant.
    2435              : 
    2436              :         @par Exception Safety
    2437              :         No-throw guarantee.
    2438              : 
    2439              :         @return `boost::system::result<T>` with either the converted number or
    2440              :             an `error_code`.
    2441              :     */
    2442              :     template<class T>
    2443              : #ifdef BOOST_JSON_DOCS
    2444              :     system::result<T>
    2445              : #else
    2446              :     typename std::enable_if<
    2447              :         std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
    2448              :         system::result<T>
    2449              :     >::type
    2450              : #endif
    2451          196 :     try_to_number() const noexcept
    2452              :     {
    2453          196 :         system::error_code ec;
    2454          196 :         T result = to_number<T>(ec);
    2455          196 :         if( ec )
    2456           78 :             return {system::in_place_error, ec};
    2457              : 
    2458          118 :         return {system::in_place_value, result};
    2459              :     }
    2460              : 
    2461              :     /** Return the stored number cast to an arithmetic type.
    2462              : 
    2463              :         This function attempts to return the stored value
    2464              :         converted to the arithmetic type `T` which may not
    2465              :         be `bool`:
    2466              : 
    2467              :         @li If `T` is an integral type and the stored
    2468              :         value is a number which can be losslessly converted,
    2469              :         the conversion is performed without error and the
    2470              :         converted number is returned.
    2471              : 
    2472              :         @li If `T` is an integral type and the stored value
    2473              :         is a number which cannot be losslessly converted,
    2474              :         then the operation fails with an error.
    2475              : 
    2476              :         @li If `T` is a floating point type and the stored
    2477              :         value is a number, the conversion is performed
    2478              :         without error. The converted number is returned,
    2479              :         with a possible loss of precision.
    2480              : 
    2481              :         @li Otherwise, if the stored value is not a number;
    2482              :         that is, if `this->is_number()` returns `false`, then
    2483              :         the operation fails with an error.
    2484              : 
    2485              :         @par Constraints
    2486              :         @code
    2487              :         std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
    2488              :         @endcode
    2489              : 
    2490              :         @par Complexity
    2491              :         Constant.
    2492              : 
    2493              :         @return The converted number.
    2494              : 
    2495              :         @throw `boost::system::system_error` Thrown on error.
    2496              :     */
    2497              :     template<class T>
    2498              : #ifdef BOOST_JSON_DOCS
    2499              :     T
    2500              : #else
    2501              :     typename std::enable_if<
    2502              :         std::is_arithmetic<T>::value &&
    2503              :         ! std::is_same<T, bool>::value,
    2504              :             T>::type
    2505              : #endif
    2506          194 :     to_number() const
    2507              :     {
    2508          194 :         return try_to_number<T>().value();
    2509              :     }
    2510              : 
    2511              :     //------------------------------------------------------
    2512              :     //
    2513              :     // Accessors
    2514              :     //
    2515              :     //------------------------------------------------------
    2516              : 
    2517              :     /** Return the associated memory resource.
    2518              : 
    2519              :         This function returns the `boost::container::pmr::memory_resource` used
    2520              :         by the container.
    2521              : 
    2522              :         @par Complexity
    2523              :         Constant.
    2524              : 
    2525              :         @par Exception Safety
    2526              :         No-throw guarantee.
    2527              :     */
    2528              :     storage_ptr const&
    2529        75308 :     storage() const noexcept
    2530              :     {
    2531        75308 :         return sp_;
    2532              :     }
    2533              : 
    2534              :     /** Return the associated allocator.
    2535              : 
    2536              :         This function returns an instance of @ref allocator_type constructed
    2537              :         from the associated `boost::container::pmr::memory_resource`.
    2538              : 
    2539              :         @par Complexity
    2540              :         Constant.
    2541              : 
    2542              :         @par Exception Safety
    2543              :         No-throw guarantee.
    2544              :     */
    2545              :     allocator_type
    2546            1 :     get_allocator() const noexcept
    2547              :     {
    2548            1 :         return sp_.get();
    2549              :     }
    2550              : 
    2551              :     //------------------------------------------------------
    2552              : 
    2553              :     /** Return `result` with a reference to the underlying @ref array
    2554              : 
    2555              :         If @ref is_array() is `true`, the result contains a reference to the
    2556              :         underlying @ref array, otherwise it contains an `error_code`.
    2557              : 
    2558              :         @par Example
    2559              :         The return value can be used in both a boolean context and
    2560              :         to assign a variable:
    2561              :         @code
    2562              :         if( auto r = jv.try_as_array() )
    2563              :             return *r;
    2564              :         @endcode
    2565              : 
    2566              :         But can also be used to throw an exception on error:
    2567              :         @code
    2568              :         return jv.try_as_array().value();
    2569              :         @endcode
    2570              : 
    2571              :         @par Complexity
    2572              :         Constant.
    2573              : 
    2574              :         @par Exception Safety
    2575              :         No-throw guarantee.
    2576              :     */
    2577              :     /** @{ */
    2578              :     BOOST_JSON_DECL
    2579              :     system::result<array&>
    2580              :     try_as_array() noexcept;
    2581              : 
    2582              :     BOOST_JSON_DECL
    2583              :     system::result<array const&>
    2584              :     try_as_array() const noexcept;
    2585              :     /** @} */
    2586              : 
    2587              :     /** Return `result` with a reference to the underlying @ref object
    2588              : 
    2589              :         If @ref is_object() is `true`, the result contains a reference to the
    2590              :         underlying @ref object, otherwise it contains an `error_code`.
    2591              : 
    2592              :         @par Example
    2593              :         The return value can be used in both a boolean context and
    2594              :         to assign a variable:
    2595              :         @code
    2596              :         if( auto r = jv.try_as_object() )
    2597              :             return *r;
    2598              :         @endcode
    2599              : 
    2600              :         But can also be used to throw an exception on error:
    2601              :         @code
    2602              :         return jv.try_as_object().value();
    2603              :         @endcode
    2604              : 
    2605              :         @par Complexity
    2606              :         Constant.
    2607              : 
    2608              :         @par Exception Safety
    2609              :         No-throw guarantee.
    2610              :     */
    2611              :     /** @{ */
    2612              :     BOOST_JSON_DECL
    2613              :     system::result<object&>
    2614              :     try_as_object() noexcept;
    2615              : 
    2616              :     BOOST_JSON_DECL
    2617              :     system::result<object const&>
    2618              :     try_as_object() const noexcept;
    2619              :     /** @} */
    2620              : 
    2621              :     /** Return `result` with a reference to the underlying @ref string
    2622              : 
    2623              :         If @ref is_string() is `true`, the result contains a reference to the
    2624              :         underlying @ref string, otherwise it contains an `error_code`.
    2625              : 
    2626              :         @par Example
    2627              :         The return value can be used in both a boolean context and
    2628              :         to assign a variable:
    2629              :         @code
    2630              :         if( auto r = jv.try_as_string() )
    2631              :             return *r;
    2632              :         @endcode
    2633              : 
    2634              :         But can also be used to throw an exception on error:
    2635              :         @code
    2636              :         return jv.try_as_string().value();
    2637              :         @endcode
    2638              : 
    2639              :         @par Complexity
    2640              :         Constant.
    2641              : 
    2642              :         @par Exception Safety
    2643              :         No-throw guarantee.
    2644              :     */
    2645              :     /** @{ */
    2646              :     BOOST_JSON_DECL
    2647              :     system::result<string&>
    2648              :     try_as_string() noexcept;
    2649              : 
    2650              :     BOOST_JSON_DECL
    2651              :     system::result<string const&>
    2652              :     try_as_string() const noexcept;
    2653              :     /** @} */
    2654              : 
    2655              :     /** Return `result` with a reference to the underlying `std::int64_t`
    2656              : 
    2657              :         If @ref is_int64() is `true`, the result contains a reference to the
    2658              :         underlying `std::int64_t`, otherwise it contains an `error_code`.
    2659              : 
    2660              :         @par Example
    2661              :         The return value can be used in both a boolean context and
    2662              :         to assign a variable:
    2663              :         @code
    2664              :         if( auto r = jv.try_as_int64() )
    2665              :             return *r;
    2666              :         @endcode
    2667              : 
    2668              :         But can also be used to throw an exception on error:
    2669              :         @code
    2670              :         return jv.try_as_int64().value();
    2671              :         @endcode
    2672              : 
    2673              :         @par Complexity
    2674              :         Constant.
    2675              : 
    2676              :         @par Exception Safety
    2677              :         No-throw guarantee.
    2678              :     */
    2679              :     BOOST_JSON_DECL
    2680              :     system::result<std::int64_t&>
    2681              :     try_as_int64() noexcept;
    2682              : 
    2683              :     /** Return `result` with the underlying `std::int64_t`
    2684              : 
    2685              :         If @ref is_int64() is `true`, the result contains a copy of the
    2686              :         underlying `std::int64_t`, otherwise it contains an `error_code`.
    2687              : 
    2688              :         @par Example
    2689              :         The return value can be used in both a boolean context and
    2690              :         to assign a variable:
    2691              :         @code
    2692              :         if( auto r = jv.try_as_int64() )
    2693              :             return *r;
    2694              :         @endcode
    2695              : 
    2696              :         But can also be used to throw an exception on error:
    2697              :         @code
    2698              :         return jv.try_as_int64().value();
    2699              :         @endcode
    2700              : 
    2701              :         @par Complexity
    2702              :         Constant.
    2703              : 
    2704              :         @par Exception Safety
    2705              :         No-throw guarantee.
    2706              :     */
    2707              :     BOOST_JSON_DECL
    2708              :     system::result<std::int64_t>
    2709              :     try_as_int64() const noexcept;
    2710              : 
    2711              :     /** Return `result` with a reference to the underlying `std::uint64_t`
    2712              : 
    2713              :         If @ref is_uint64() is `true`, the result contains a reference to the
    2714              :         underlying `std::uint64_t`, otherwise it contains an `error_code`.
    2715              : 
    2716              :         @par Example
    2717              :         The return value can be used in both a boolean context and
    2718              :         to assign a variable:
    2719              :         @code
    2720              :         if( auto r = jv.try_as_uint64() )
    2721              :             return *r;
    2722              :         @endcode
    2723              : 
    2724              :         But can also be used to throw an exception on error:
    2725              :         @code
    2726              :         return jv.try_as_uint64().value();
    2727              :         @endcode
    2728              : 
    2729              :         @par Complexity
    2730              :         Constant.
    2731              : 
    2732              :         @par Exception Safety
    2733              :         No-throw guarantee.
    2734              :     */
    2735              :     BOOST_JSON_DECL
    2736              :     system::result<std::uint64_t&>
    2737              :     try_as_uint64() noexcept;
    2738              : 
    2739              :     /** Return `result` with the underlying `std::uint64_t`
    2740              : 
    2741              :         If @ref is_uint64() is `true`, the result contains a copy of the
    2742              :         underlying `std::uint64_t`, otherwise it contains an `error_code`.
    2743              : 
    2744              :         @par Example
    2745              :         The return value can be used in both a boolean context and
    2746              :         to assign a variable:
    2747              :         @code
    2748              :         if( auto r = jv.try_as_uint64() )
    2749              :             return *r;
    2750              :         @endcode
    2751              : 
    2752              :         But can also be used to throw an exception on error:
    2753              :         @code
    2754              :         return jv.try_as_uint64().value();
    2755              :         @endcode
    2756              : 
    2757              :         @par Complexity
    2758              :         Constant.
    2759              : 
    2760              :         @par Exception Safety
    2761              :         No-throw guarantee.
    2762              :     */
    2763              :     BOOST_JSON_DECL
    2764              :     system::result<std::uint64_t>
    2765              :     try_as_uint64() const noexcept;
    2766              : 
    2767              :     /** Return `result` with a reference to the underlying `double`
    2768              : 
    2769              :         If @ref is_double() is `true`, the result contains a reference to the
    2770              :         underlying `double`, otherwise it contains an `error_code`.
    2771              : 
    2772              :         @par Example
    2773              :         The return value can be used in both a boolean context and
    2774              :         to assign a variable:
    2775              :         @code
    2776              :         if( auto r = jv.try_as_double() )
    2777              :             return *r;
    2778              :         @endcode
    2779              : 
    2780              :         But can also be used to throw an exception on error:
    2781              :         @code
    2782              :         return jv.try_as_double().value();
    2783              :         @endcode
    2784              : 
    2785              :         @par Complexity
    2786              :         Constant.
    2787              : 
    2788              :         @par Exception Safety
    2789              :         No-throw guarantee.
    2790              :     */
    2791              :     BOOST_JSON_DECL
    2792              :     system::result<double&>
    2793              :     try_as_double() noexcept;
    2794              : 
    2795              :     /** Return `result` with the underlying `double`
    2796              : 
    2797              :         If @ref is_double() is `true`, the result contains a copy of the
    2798              :         underlying `double`, otherwise it contains an `error_code`.
    2799              : 
    2800              :         @par Example
    2801              :         The return value can be used in both a boolean context and
    2802              :         to assign a variable:
    2803              :         @code
    2804              :         if( auto r = jv.try_as_double() )
    2805              :             return *r;
    2806              :         @endcode
    2807              : 
    2808              :         But can also be used to throw an exception on error:
    2809              :         @code
    2810              :         return jv.try_as_double().value();
    2811              :         @endcode
    2812              : 
    2813              :         @par Complexity
    2814              :         Constant.
    2815              : 
    2816              :         @par Exception Safety
    2817              :         No-throw guarantee.
    2818              :     */
    2819              :     BOOST_JSON_DECL
    2820              :     system::result<double>
    2821              :     try_as_double() const noexcept;
    2822              : 
    2823              :     /** Return `result` with a reference to the underlying `bool`
    2824              : 
    2825              :         If @ref is_bool() is `true`, the result contains a reference to the
    2826              :         underlying `bool`, otherwise it contains an `error_code`.
    2827              : 
    2828              :         @par Example
    2829              :         The return value can be used in both a boolean context and
    2830              :         to assign a variable:
    2831              :         @code
    2832              :         if( auto r = jv.try_as_bool() )
    2833              :             return *r;
    2834              :         @endcode
    2835              : 
    2836              :         But can also be used to throw an exception on error:
    2837              :         @code
    2838              :         return jv.try_as_bool().value();
    2839              :         @endcode
    2840              : 
    2841              :         @par Complexity
    2842              :         Constant.
    2843              : 
    2844              :         @par Exception Safety
    2845              :         No-throw guarantee.
    2846              :     */
    2847              :     BOOST_JSON_DECL
    2848              :     system::result<bool&>
    2849              :     try_as_bool() noexcept;
    2850              : 
    2851              :     /** Return `result` with the underlying `bool`
    2852              : 
    2853              :         If @ref is_bool() is `true`, the result contains a copy of the
    2854              :         underlying `bool`, otherwise it contains an `error_code`.
    2855              : 
    2856              :         @par Example
    2857              :         The return value can be used in both a boolean context and
    2858              :         to assign a variable:
    2859              :         @code
    2860              :         if( auto r = jv.try_as_bool() )
    2861              :             return *r;
    2862              :         @endcode
    2863              : 
    2864              :         But can also be used to throw an exception on error:
    2865              :         @code
    2866              :         return jv.try_as_bool().value();
    2867              :         @endcode
    2868              : 
    2869              :         @par Complexity
    2870              :         Constant.
    2871              : 
    2872              :         @par Exception Safety
    2873              :         No-throw guarantee.
    2874              :     */
    2875              :     BOOST_JSON_DECL
    2876              :     system::result<bool>
    2877              :     try_as_bool() const noexcept;
    2878              : 
    2879              :     /** Return engaged `result` if the `value` is null
    2880              : 
    2881              :         If @ref is_null() is `true`, the result is engaged, otherwise it
    2882              :         contains an `error_code`.
    2883              : 
    2884              :         @par Example
    2885              :         The return value can be used in both a boolean context and
    2886              :         to assign a variable:
    2887              :         @code
    2888              :         if( auto r = jv.try_as_null() )
    2889              :             return *r;
    2890              :         @endcode
    2891              : 
    2892              :         But can also be used to throw an exception on error:
    2893              :         @code
    2894              :         return jv.try_as_null().value();
    2895              :         @endcode
    2896              : 
    2897              :         @par Complexity
    2898              :         Constant.
    2899              : 
    2900              :         @par Exception Safety
    2901              :         No-throw guarantee.
    2902              :     */
    2903              :     BOOST_JSON_DECL
    2904              :     system::result<std::nullptr_t>
    2905              :     try_as_null() const noexcept;
    2906              : 
    2907              :     //------------------------------------------------------
    2908              : 
    2909              :     /** Return a reference to the underlying `object`, or throw an exception.
    2910              : 
    2911              :         If @ref is_object() is `true`, returns
    2912              :         a reference to the underlying @ref object,
    2913              :         otherwise throws an exception.
    2914              : 
    2915              :         @par Exception Safety
    2916              :         Strong guarantee.
    2917              : 
    2918              :         @throw `boost::system::system_error` `! this->is_object()`.
    2919              : 
    2920              :         @param loc `source_location` to use in thrown exception; the source
    2921              :             location of the call site by default.
    2922              : 
    2923              :         @par Complexity
    2924              :         Constant.
    2925              :     */
    2926              :     /** @{ */
    2927              :     object&
    2928          165 :     as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
    2929              :     {
    2930          165 :         auto& self = const_cast<value const&>(*this);
    2931          165 :         return const_cast<object&>( self.as_object(loc) );
    2932              :     }
    2933              : 
    2934              :     object&&
    2935           97 :     as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
    2936              :     {
    2937           97 :         return std::move( as_object(loc) );
    2938              :     }
    2939              : 
    2940              :     BOOST_JSON_DECL
    2941              :     object const&
    2942              :     as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
    2943              :     /** @} */
    2944              : 
    2945              :     /** Return a reference to the underlying @ref array, or throw an exception.
    2946              : 
    2947              :         If @ref is_array() is `true`, returns
    2948              :         a reference to the underlying @ref array,
    2949              :         otherwise throws an exception.
    2950              : 
    2951              :         @par Exception Safety
    2952              :         Strong guarantee.
    2953              : 
    2954              :         @throw `boost::system::system_error` `! this->is_array()`.
    2955              : 
    2956              :         @param loc `source_location` to use in thrown exception; the source
    2957              :             location of the call site by default.
    2958              : 
    2959              :         @par Complexity
    2960              :         Constant.
    2961              :     */
    2962              :     /** @{ */
    2963              :     array&
    2964           92 :     as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
    2965              :     {
    2966           92 :         auto& self = const_cast<value const&>(*this);
    2967           92 :         return const_cast<array&>( self.as_array(loc) );
    2968              :     }
    2969              : 
    2970              :     array&&
    2971           10 :     as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
    2972              :     {
    2973           10 :         return std::move( as_array(loc) );
    2974              :     }
    2975              : 
    2976              :     BOOST_JSON_DECL
    2977              :     array const&
    2978              :     as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
    2979              :     /** @} */
    2980              : 
    2981              :     /** Return a reference to the underlying `string`, or throw an exception.
    2982              : 
    2983              :         If @ref is_string() is `true`, returns
    2984              :         a reference to the underlying @ref string,
    2985              :         otherwise throws an exception.
    2986              : 
    2987              :         @par Exception Safety
    2988              :         Strong guarantee.
    2989              : 
    2990              :         @throw `boost::system::system_error` `! this->is_string()`.
    2991              : 
    2992              :         @param loc `source_location` to use in thrown exception; the source
    2993              :             location of the call site by default.
    2994              : 
    2995              :         @par Complexity
    2996              :         Constant.
    2997              :     */
    2998              :     string&
    2999           34 :     as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
    3000              :     {
    3001           34 :         auto& self = const_cast<value const&>(*this);
    3002           34 :         return const_cast<string&>( self.as_string(loc) );
    3003              :     }
    3004              : 
    3005              :     /** Return a reference to the underlying `string`, or throw an exception.
    3006              : 
    3007              :         If @ref is_string() is `true`, returns
    3008              :         a reference to the underlying @ref string,
    3009              :         otherwise throws an exception.
    3010              : 
    3011              :         @par Exception Safety
    3012              :         Strong guarantee.
    3013              : 
    3014              :         @throw `boost::system::system_error` `! this->is_string()`.
    3015              : 
    3016              :         @param loc `source_location` to use in thrown exception; the source
    3017              :             location of the call site by default.
    3018              : 
    3019              :         @par Complexity
    3020              :         Constant.
    3021              :     */
    3022              :     /** @{ */
    3023              :     string&&
    3024           12 :     as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
    3025              :     {
    3026           12 :         return std::move( as_string(loc) );
    3027              :     }
    3028              : 
    3029              :     BOOST_JSON_DECL
    3030              :     string const&
    3031              :     as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
    3032              : 
    3033              :     BOOST_JSON_DECL
    3034              :     std::int64_t&
    3035              :     as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
    3036              :     /** @} */
    3037              : 
    3038              :     /** Return the underlying `std::int64_t`, or throw an exception.
    3039              : 
    3040              :         If @ref is_int64() is `true`, returns
    3041              :         the underlying `std::int64_t`,
    3042              :         otherwise throws an exception.
    3043              : 
    3044              :         @par Exception Safety
    3045              :         Strong guarantee.
    3046              : 
    3047              :         @throw `boost::system::system_error` `! this->is_int64()`.
    3048              : 
    3049              :         @param loc `source_location` to use in thrown exception; the source
    3050              :             location of the call site by default.
    3051              : 
    3052              :         @par Complexity
    3053              :         Constant.
    3054              : 
    3055              :         @par Note
    3056              :         This function is the const-qualified overload of @ref as_int64, which
    3057              :         is intended for direct access to the underlying object, __if__ it has
    3058              :         the type `std::int64_t`. It does not convert the underlying object to
    3059              :         type `std::int64_t` even if a lossless conversion is possible. If you
    3060              :         are not sure which kind your `value` has, and you only care about
    3061              :         getting a `std::int64_t` number, consider using @ref to_number instead.
    3062              :     */
    3063              :     BOOST_JSON_DECL
    3064              :     std::int64_t
    3065              :     as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
    3066              : 
    3067              :     /** Return a reference to the underlying `std::uint64_t`, or throw an exception.
    3068              : 
    3069              :         If @ref is_uint64() is `true`, returns
    3070              :         a reference to the underlying `std::uint64_t`,
    3071              :         otherwise throws an exception.
    3072              : 
    3073              :         @par Exception Safety
    3074              :         Strong guarantee.
    3075              : 
    3076              :         @throw `boost::system::system_error` `! this->is_uint64()`.
    3077              : 
    3078              :         @param loc `source_location` to use in thrown exception; the source
    3079              :             location of the call site by default.
    3080              : 
    3081              :         @par Complexity
    3082              :         Constant.
    3083              : 
    3084              :         @par Note
    3085              :         This function is intended for direct access to the underlying object,
    3086              :         __if__ it has the type `std::uint64_t`. It does not convert the
    3087              :         underlying object to type `std::uint64_t` even if a lossless conversion
    3088              :         is possible. If you are not sure which kind your `value` has, and you
    3089              :         only care about getting a `std::uint64_t` number, consider using
    3090              :         @ref to_number instead.
    3091              :     */
    3092              :     BOOST_JSON_DECL
    3093              :     std::uint64_t&
    3094              :     as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
    3095              : 
    3096              :     /** Return the underlying `std::uint64_t`, or throw an exception.
    3097              : 
    3098              :         If @ref is_uint64() is `true`, returns
    3099              :         the underlying `std::uint64_t`,
    3100              :         otherwise throws an exception.
    3101              : 
    3102              :         @par Exception Safety
    3103              :         Strong guarantee.
    3104              : 
    3105              :         @throw `boost::system::system_error` `! this->is_uint64()`.
    3106              : 
    3107              :         @param loc `source_location` to use in thrown exception; the source
    3108              :             location of the call site by default.
    3109              : 
    3110              :         @par Complexity
    3111              :         Constant.
    3112              : 
    3113              :         @par Note
    3114              :         This function is the const-qualified overload of @ref as_uint64, which
    3115              :         is intended for direct access to the underlying object, __if__ it has
    3116              :         the type `std::uint64_t`. It does not convert the underlying object to
    3117              :         type `std::uint64_t` even if a lossless conversion is possible. If you
    3118              :         are not sure which kind your `value` has, and you only care about
    3119              :         getting a `std::uint64_t` number, consider using
    3120              :         @ref to_number instead.
    3121              :     */
    3122              :     BOOST_JSON_DECL
    3123              :     std::uint64_t
    3124              :     as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
    3125              : 
    3126              :     /** Return a reference to the underlying `double`, or throw an exception.
    3127              : 
    3128              :         If @ref is_double() is `true`, returns
    3129              :         a reference to the underlying `double`,
    3130              :         otherwise throws an exception.
    3131              : 
    3132              :         @par Exception Safety
    3133              :         Strong guarantee.
    3134              : 
    3135              :         @throw `boost::system::system_error` `! this->is_double()`.
    3136              : 
    3137              :         @param loc `source_location` to use in thrown exception; the source
    3138              :             location of the call site by default.
    3139              : 
    3140              :         @par Complexity
    3141              :         Constant.
    3142              : 
    3143              :         @par Note
    3144              :         This function is intended for direct access to the underlying object,
    3145              :         __if__ it has the type `double`. It does not convert the underlying
    3146              :         object to type `double` even if a lossless conversion is possible. If
    3147              :         you are not sure which kind your `value` has, and you only care about
    3148              :         getting a `double` number, consider using @ref to_number instead.
    3149              :     */
    3150              :     BOOST_JSON_DECL
    3151              :     double&
    3152              :     as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
    3153              : 
    3154              :     /** Return the underlying `double`, or throw an exception.
    3155              : 
    3156              :         If @ref is_double() is `true`, returns
    3157              :         the underlying `double`,
    3158              :         otherwise throws an exception.
    3159              : 
    3160              :         @par Exception Safety
    3161              :         Strong guarantee.
    3162              : 
    3163              :         @throw `boost::system::system_error` `! this->is_double()`.
    3164              : 
    3165              :         @param loc `source_location` to use in thrown exception; the source
    3166              :             location of the call site by default.
    3167              : 
    3168              :         @par Complexity
    3169              :         Constant.
    3170              : 
    3171              :         @par Note
    3172              :         This function is the const-qualified overload of @ref as_double, which
    3173              :         is intended for direct access to the underlying object, __if__ it has
    3174              :         the type `double`. It does not convert the underlying object to type
    3175              :         `double` even if a lossless conversion is possible. If you are not sure
    3176              :         which kind your `value` has, and you only care about getting a `double`
    3177              :         number, consider using @ref to_number instead.
    3178              :     */
    3179              :     BOOST_JSON_DECL
    3180              :     double
    3181              :     as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
    3182              : 
    3183              :     /** Return a reference to the underlying `bool`, or throw an exception.
    3184              : 
    3185              :         If @ref is_bool() is `true`, returns
    3186              :         a reference to the underlying `bool`,
    3187              :         otherwise throws an exception.
    3188              : 
    3189              :         @par Exception Safety
    3190              :         Strong guarantee.
    3191              : 
    3192              :         @throw `boost::system::system_error` `! this->is_bool()`.
    3193              : 
    3194              :         @param loc `source_location` to use in thrown exception; the source
    3195              :             location of the call site by default.
    3196              : 
    3197              :         @par Complexity
    3198              :         Constant.
    3199              :     */
    3200              :     BOOST_JSON_DECL
    3201              :     bool&
    3202              :     as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
    3203              : 
    3204              :     /** Return the underlying `bool`, or throw an exception.
    3205              : 
    3206              :         If @ref is_bool() is `true`, returns
    3207              :         the underlying `bool`,
    3208              :         otherwise throws an exception.
    3209              : 
    3210              :         @par Exception Safety
    3211              :         Strong guarantee.
    3212              : 
    3213              :         @throw `boost::system::system_error` `! this->is_bool()`.
    3214              : 
    3215              :         @param loc `source_location` to use in thrown exception; the source
    3216              :             location of the call site by default.
    3217              : 
    3218              :         @par Complexity
    3219              :         Constant.
    3220              :     */
    3221              :     BOOST_JSON_DECL
    3222              :     bool
    3223              :     as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
    3224              : 
    3225              :     //------------------------------------------------------
    3226              : 
    3227              :     /** Return a reference to the underlying `object`, without checking.
    3228              : 
    3229              :         This is the fastest way to access the underlying
    3230              :         representation when the kind is known in advance.
    3231              : 
    3232              :         @par Preconditions
    3233              : 
    3234              :         @code
    3235              :         this->is_object()
    3236              :         @endcode
    3237              : 
    3238              :         @par Complexity
    3239              :         Constant.
    3240              : 
    3241              :         @par Exception Safety
    3242              :         No-throw guarantee.
    3243              :     */
    3244              :     /** @{ */
    3245              :     object&
    3246           38 :     get_object() & noexcept
    3247              :     {
    3248           38 :         BOOST_ASSERT(is_object());
    3249           38 :         return obj_;
    3250              :     }
    3251              : 
    3252              :     object&&
    3253            1 :     get_object() && noexcept
    3254              :     {
    3255            1 :         BOOST_ASSERT(is_object());
    3256            1 :         return std::move(obj_);
    3257              :     }
    3258              : 
    3259              :     object const&
    3260        52907 :     get_object() const& noexcept
    3261              :     {
    3262        52907 :         BOOST_ASSERT(is_object());
    3263        52907 :         return obj_;
    3264              :     }
    3265              :     /** @} */
    3266              : 
    3267              :     /** Return a reference to the underlying `array`, without checking.
    3268              : 
    3269              :         This is the fastest way to access the underlying
    3270              :         representation when the kind is known in advance.
    3271              : 
    3272              :         @par Preconditions
    3273              : 
    3274              :         @code
    3275              :         this->is_array()
    3276              :         @endcode
    3277              : 
    3278              :         @par Complexity
    3279              :         Constant.
    3280              : 
    3281              :         @par Exception Safety
    3282              :         No-throw guarantee.
    3283              :     */
    3284              :     /** @{ */
    3285              :     array&
    3286           25 :     get_array() & noexcept
    3287              :     {
    3288           25 :         BOOST_ASSERT(is_array());
    3289           25 :         return arr_;
    3290              :     }
    3291              : 
    3292              :     array&&
    3293            1 :     get_array() && noexcept
    3294              :     {
    3295            1 :         BOOST_ASSERT(is_array());
    3296            1 :         return std::move(arr_);
    3297              :     }
    3298              : 
    3299              :     array const&
    3300         5582 :     get_array() const& noexcept
    3301              :     {
    3302         5582 :         BOOST_ASSERT(is_array());
    3303         5582 :         return arr_;
    3304              :     }
    3305              :     /** @} */
    3306              : 
    3307              :     /** Return a reference to the underlying `string`, without checking.
    3308              : 
    3309              :         This is the fastest way to access the underlying
    3310              :         representation when the kind is known in advance.
    3311              : 
    3312              :         @par Preconditions
    3313              : 
    3314              :         @code
    3315              :         this->is_string()
    3316              :         @endcode
    3317              : 
    3318              :         @par Complexity
    3319              :         Constant.
    3320              : 
    3321              :         @par Exception Safety
    3322              :         No-throw guarantee.
    3323              :     */
    3324              :     /** @{ */
    3325              :     string&
    3326         8971 :     get_string() & noexcept
    3327              :     {
    3328         8971 :         BOOST_ASSERT(is_string());
    3329         8971 :         return str_;
    3330              :     }
    3331              : 
    3332              :     string&&
    3333            1 :     get_string() && noexcept
    3334              :     {
    3335            1 :         BOOST_ASSERT(is_string());
    3336            1 :         return std::move(str_);
    3337              :     }
    3338              : 
    3339              :     string const&
    3340        40831 :     get_string() const& noexcept
    3341              :     {
    3342        40831 :         BOOST_ASSERT(is_string());
    3343        40831 :         return str_;
    3344              :     }
    3345              :     /** @} */
    3346              : 
    3347              :     /** Return a reference to the underlying `std::int64_t`, without checking.
    3348              : 
    3349              :         This is the fastest way to access the underlying
    3350              :         representation when the kind is known in advance.
    3351              : 
    3352              :         @par Preconditions
    3353              : 
    3354              :         @code
    3355              :         this->is_int64()
    3356              :         @endcode
    3357              : 
    3358              :         @par Complexity
    3359              :         Constant.
    3360              : 
    3361              :         @par Exception Safety
    3362              :         No-throw guarantee.
    3363              :     */
    3364              :     std::int64_t&
    3365            4 :     get_int64() noexcept
    3366              :     {
    3367            4 :         BOOST_ASSERT(is_int64());
    3368            4 :         return sca_.i;
    3369              :     }
    3370              : 
    3371              :     /** Return the underlying `std::int64_t`, without checking.
    3372              : 
    3373              :         This is the fastest way to access the underlying
    3374              :         representation when the kind is known in advance.
    3375              : 
    3376              :         @par Preconditions
    3377              : 
    3378              :         @code
    3379              :         this->is_int64()
    3380              :         @endcode
    3381              : 
    3382              :         @par Complexity
    3383              :         Constant.
    3384              : 
    3385              :         @par Exception Safety
    3386              :         No-throw guarantee.
    3387              :     */
    3388              :     std::int64_t
    3389        14191 :     get_int64() const noexcept
    3390              :     {
    3391        14191 :         BOOST_ASSERT(is_int64());
    3392        14191 :         return sca_.i;
    3393              :     }
    3394              : 
    3395              :     /** Return a reference to the underlying `std::uint64_t`, without checking.
    3396              : 
    3397              :         This is the fastest way to access the underlying
    3398              :         representation when the kind is known in advance.
    3399              : 
    3400              :         @par Preconditions
    3401              : 
    3402              :         @code
    3403              :         this->is_uint64()
    3404              :         @endcode
    3405              : 
    3406              :         @par Complexity
    3407              :         Constant.
    3408              : 
    3409              :         @par Exception Safety
    3410              :         No-throw guarantee.
    3411              :     */
    3412              :     std::uint64_t&
    3413            4 :     get_uint64() noexcept
    3414              :     {
    3415            4 :         BOOST_ASSERT(is_uint64());
    3416            4 :         return sca_.u;
    3417              :     }
    3418              : 
    3419              :     /** Return the underlying `std::uint64_t`, without checking.
    3420              : 
    3421              :         This is the fastest way to access the underlying
    3422              :         representation when the kind is known in advance.
    3423              : 
    3424              :         @par Preconditions
    3425              : 
    3426              :         @code
    3427              :         this->is_uint64()
    3428              :         @endcode
    3429              : 
    3430              :         @par Complexity
    3431              :         Constant.
    3432              : 
    3433              :         @par Exception Safety
    3434              :         No-throw guarantee.
    3435              :     */
    3436              :     std::uint64_t
    3437          209 :     get_uint64() const noexcept
    3438              :     {
    3439          209 :         BOOST_ASSERT(is_uint64());
    3440          209 :         return sca_.u;
    3441              :     }
    3442              : 
    3443              :     /** Return a reference to the underlying `double`, without checking.
    3444              : 
    3445              :         This is the fastest way to access the underlying
    3446              :         representation when the kind is known in advance.
    3447              : 
    3448              :         @par Preconditions
    3449              : 
    3450              :         @code
    3451              :         this->is_double()
    3452              :         @endcode
    3453              : 
    3454              :         @par Complexity
    3455              :         Constant.
    3456              : 
    3457              :         @par Exception Safety
    3458              :         No-throw guarantee.
    3459              :     */
    3460              :     double&
    3461            4 :     get_double() noexcept
    3462              :     {
    3463            4 :         BOOST_ASSERT(is_double());
    3464            4 :         return sca_.d;
    3465              :     }
    3466              : 
    3467              :     /** Return the underlying `double`, without checking.
    3468              : 
    3469              :         This is the fastest way to access the underlying
    3470              :         representation when the kind is known in advance.
    3471              : 
    3472              :         @par Preconditions
    3473              : 
    3474              :         @code
    3475              :         this->is_double()
    3476              :         @endcode
    3477              : 
    3478              :         @par Complexity
    3479              :         Constant.
    3480              : 
    3481              :         @par Exception Safety
    3482              :         No-throw guarantee.
    3483              :     */
    3484              :     double
    3485        39138 :     get_double() const noexcept
    3486              :     {
    3487        39138 :         BOOST_ASSERT(is_double());
    3488        39138 :         return sca_.d;
    3489              :     }
    3490              : 
    3491              :     /** Return a reference to the underlying `bool`, without checking.
    3492              : 
    3493              :         This is the fastest way to access the underlying
    3494              :         representation when the kind is known in advance.
    3495              : 
    3496              :         @par Preconditions
    3497              : 
    3498              :         @code
    3499              :         this->is_bool()
    3500              :         @endcode
    3501              : 
    3502              :         @par Complexity
    3503              :         Constant.
    3504              : 
    3505              :         @par Exception Safety
    3506              :         No-throw guarantee.
    3507              :     */
    3508              :     bool&
    3509            4 :     get_bool() noexcept
    3510              :     {
    3511            4 :         BOOST_ASSERT(is_bool());
    3512            4 :         return sca_.b;
    3513              :     }
    3514              : 
    3515              :     /** Return the underlying `bool`, without checking.
    3516              : 
    3517              :         This is the fastest way to access the underlying
    3518              :         representation when the kind is known in advance.
    3519              : 
    3520              :         @par Preconditions
    3521              : 
    3522              :         @code
    3523              :         this->is_bool()
    3524              :         @endcode
    3525              : 
    3526              :         @par Complexity
    3527              :         Constant.
    3528              : 
    3529              :         @par Exception Safety
    3530              :         No-throw guarantee.
    3531              :     */
    3532              :     bool
    3533          796 :     get_bool() const noexcept
    3534              :     {
    3535          796 :         BOOST_ASSERT(is_bool());
    3536          796 :         return sca_.b;
    3537              :     }
    3538              : 
    3539              :     //------------------------------------------------------
    3540              : 
    3541              :     /** Access an element, with bounds checking.
    3542              : 
    3543              :         Returns `boost::system::result` containing a reference to the element
    3544              :         of the underlying object, if `pos` is within its range. If `pos` is
    3545              :         outside of that range, or the underlying value is not an object the
    3546              :         result contains an `error_code`.
    3547              : 
    3548              :         @par Exception Safety
    3549              :         No-throw guarantee.
    3550              : 
    3551              :         @param key The key of the element to find.
    3552              : 
    3553              :         @par Complexity
    3554              :         Constant.
    3555              :     */
    3556              :     /** @{ */
    3557              :     BOOST_JSON_DECL
    3558              :     boost::system::result<value&>
    3559              :     try_at(string_view key) noexcept;
    3560              : 
    3561              :     BOOST_JSON_DECL
    3562              :     boost::system::result<value const&>
    3563              :     try_at(string_view key) const noexcept;
    3564              :     /** @} */
    3565              : 
    3566              :     /** Access an element, with bounds checking.
    3567              : 
    3568              :         This function is used to access elements of
    3569              :         the underlying object, or throw an exception
    3570              :         if the value is not an object.
    3571              : 
    3572              :         @par Complexity
    3573              :         Constant.
    3574              : 
    3575              :         @par Exception Safety
    3576              :         Strong guarantee.
    3577              : 
    3578              :         @param key The key of the element to find.
    3579              : 
    3580              :         @param loc `source_location` to use in thrown exception; the source
    3581              :             location of the call site by default.
    3582              : 
    3583              :         @return `this->as_object(loc).at( key, loc )`.
    3584              :     */
    3585              :     /** @{ */
    3586              :     value&
    3587           12 :     at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
    3588              :     {
    3589           12 :         return as_object(loc).at(key, loc);
    3590              :     }
    3591              : 
    3592              :     value&&
    3593            1 :     at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
    3594              :     {
    3595            1 :         return std::move( as_object(loc) ).at(key, loc);
    3596              :     }
    3597              : 
    3598              :     value const&
    3599           18 :     at(
    3600              :         string_view key,
    3601              :         source_location const& loc = BOOST_CURRENT_LOCATION) const&
    3602              :     {
    3603           18 :         return as_object(loc).at(key, loc);
    3604              :     }
    3605              :     /** @} */
    3606              : 
    3607              :     /** Access an element, with bounds checking.
    3608              : 
    3609              :         Returns `boost::system::result` containing a reference to the element
    3610              :         of the underlying array, if `pos` is within its range. If `pos` is
    3611              :         outside of that range, or the underlying value is not an array the
    3612              :         result contains an `error_code`.
    3613              : 
    3614              :         @par Exception Safety
    3615              :         No-throw guarantee.
    3616              : 
    3617              :         @param pos A zero-based array index.
    3618              : 
    3619              :         @par Complexity
    3620              :         Constant.
    3621              :     */
    3622              :     /** @{ */
    3623              :     BOOST_JSON_DECL
    3624              :     boost::system::result<value&>
    3625              :     try_at(std::size_t pos) noexcept;
    3626              : 
    3627              :     BOOST_JSON_DECL
    3628              :     boost::system::result<value const&>
    3629              :     try_at(std::size_t pos) const noexcept;
    3630              :     /** @} */
    3631              : 
    3632              :     /** Access an element, with bounds checking.
    3633              : 
    3634              :         This function is used to access elements of
    3635              :         the underlying array, or throw an exception
    3636              :         if the value is not an array.
    3637              : 
    3638              :         @par Complexity
    3639              :         Constant.
    3640              : 
    3641              :         @par Exception Safety
    3642              :         Strong guarantee.
    3643              : 
    3644              :         @param pos A zero-based array index.
    3645              : 
    3646              :         @param loc `source_location` to use in thrown exception; the source
    3647              :             location of the call site by default.
    3648              : 
    3649              :         @return `this->as_array(loc).at( pos, loc )`.
    3650              :     */
    3651              :     /** @{ */
    3652              :     value &
    3653           12 :     at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
    3654              :     {
    3655           12 :         return as_array(loc).at(pos, loc);
    3656              :     }
    3657              : 
    3658              :     value&&
    3659           10 :     at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
    3660              :     {
    3661           10 :         return std::move( as_array(loc) ).at(pos, loc);
    3662              :     }
    3663              : 
    3664              :     value const&
    3665           56 :     at(
    3666              :         std::size_t pos,
    3667              :         source_location const& loc = BOOST_CURRENT_LOCATION) const&
    3668              :     {
    3669           56 :         return as_array(loc).at(pos, loc);
    3670              :     }
    3671              :     /** @} */
    3672              : 
    3673              :     /** Access an element via JSON Pointer.
    3674              : 
    3675              :         This function is used to access a (potentially nested) element of the
    3676              :         value using a JSON Pointer string.
    3677              : 
    3678              :         @par Complexity
    3679              :         Linear in the sizes of `ptr` and underlying array, object, or string.
    3680              : 
    3681              :         @par Exception Safety
    3682              :         No-throw guarantee.
    3683              : 
    3684              :         @param ptr JSON Pointer string.
    3685              : 
    3686              :         @return `boost::system::result<value&>` containing either a reference
    3687              :             to the element identified by `ptr` or a corresponding `error_code`.
    3688              : 
    3689              :         @see
    3690              :             [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
    3691              :     */
    3692              :     BOOST_JSON_DECL
    3693              :     system::result<value const&>
    3694              :     try_at_pointer(string_view ptr) const noexcept;
    3695              : 
    3696              :     /** Access an element via JSON Pointer.
    3697              : 
    3698              :         This function is used to access a (potentially nested) element of the
    3699              :         value using a JSON Pointer string.
    3700              : 
    3701              :         @par Complexity
    3702              :         Linear in the sizes of `ptr` and underlying array, object, or string.
    3703              : 
    3704              :         @par Exception Safety
    3705              :         No-throw guarantee.
    3706              : 
    3707              :         @param ptr JSON Pointer string.
    3708              : 
    3709              :         @return `boost::system::result<value const&>` containing either a
    3710              :             reference to the element identified by `ptr` or a corresponding
    3711              :             `error_code`.
    3712              : 
    3713              :         @see
    3714              :             [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
    3715              :     */
    3716              :     BOOST_JSON_DECL
    3717              :     system::result<value&>
    3718              :     try_at_pointer(string_view ptr) noexcept;
    3719              : 
    3720              :     /** Access an element via JSON Pointer.
    3721              : 
    3722              :         This function is used to access a (potentially nested)
    3723              :         element of the value using a JSON Pointer string.
    3724              : 
    3725              :         @par Complexity
    3726              :         Linear in the sizes of `ptr` and underlying array, object, or string.
    3727              : 
    3728              :         @par Exception Safety
    3729              :         Strong guarantee.
    3730              : 
    3731              :         @param ptr JSON Pointer string.
    3732              : 
    3733              :         @param loc `source_location` to use in thrown exception; the source
    3734              :             location of the call site by default.
    3735              : 
    3736              :         @return reference to the element identified by `ptr`.
    3737              : 
    3738              :         @throw `boost::system::system_error` if an error occurs.
    3739              : 
    3740              :         @see
    3741              :         <a href="https://datatracker.ietf.org/doc/html/rfc6901">
    3742              :             RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
    3743              :     */
    3744              :     /** @{ */
    3745              :     BOOST_JSON_DECL
    3746              :     value const&
    3747              :     at_pointer(
    3748              :         string_view ptr,
    3749              :         source_location const& loc = BOOST_CURRENT_LOCATION) const&;
    3750              : 
    3751              :     inline
    3752              :     value&&
    3753              :     at_pointer(
    3754              :         string_view ptr,
    3755              :         source_location const& loc = BOOST_CURRENT_LOCATION) &&;
    3756              : 
    3757              :     inline
    3758              :     value&
    3759              :     at_pointer(
    3760              :         string_view ptr,
    3761              :         source_location const& loc = BOOST_CURRENT_LOCATION) &;
    3762              :     /** @} */
    3763              : 
    3764              :     /** Access an element via JSON Pointer.
    3765              : 
    3766              :         This function is used to access a (potentially nested)
    3767              :         element of the value using a JSON Pointer string.
    3768              : 
    3769              :         @par Complexity
    3770              :         Linear in the sizes of `ptr` and underlying array, object, or string.
    3771              : 
    3772              :         @par Exception Safety
    3773              :         No-throw guarantee.
    3774              : 
    3775              :         @param ptr JSON Pointer string.
    3776              : 
    3777              :         @param ec Set to the error, if any occurred.
    3778              : 
    3779              :         @return pointer to the element identified by `ptr`.
    3780              : 
    3781              :         @see
    3782              :         <a href="https://datatracker.ietf.org/doc/html/rfc6901">
    3783              :             RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
    3784              :     */
    3785              :     /** @{ */
    3786              :     BOOST_JSON_DECL
    3787              :     value const*
    3788              :     find_pointer(string_view ptr, system::error_code& ec) const noexcept;
    3789              : 
    3790              :     BOOST_JSON_DECL
    3791              :     value*
    3792              :     find_pointer(string_view ptr, system::error_code& ec) noexcept;
    3793              : 
    3794              :     BOOST_JSON_DECL
    3795              :     value const*
    3796              :     find_pointer(string_view ptr, std::error_code& ec) const noexcept;
    3797              : 
    3798              :     BOOST_JSON_DECL
    3799              :     value*
    3800              :     find_pointer(string_view ptr, std::error_code& ec) noexcept;
    3801              :     /** @} */
    3802              : 
    3803              :     //------------------------------------------------------
    3804              : 
    3805              :     /** Set an element via JSON Pointer.
    3806              : 
    3807              :         This function is used to insert or assign to a potentially nested
    3808              :         element of the value using a JSON Pointer string. The function may
    3809              :         create intermediate elements corresponding to pointer segments.
    3810              :         <br/>
    3811              : 
    3812              :         The particular conditions when and what kind of intermediate element
    3813              :         is created is governed by the `ptr` parameter.
    3814              : 
    3815              :         Each pointer token is considered in sequence. For each token
    3816              : 
    3817              :         - if the containing value is an @ref object, then a new `null`
    3818              :           element is created with key equal to unescaped token string;
    3819              :           otherwise
    3820              : 
    3821              :         - if the containing value is an @ref array, and the token represents a
    3822              :           past-the-end marker, then a `null` element is appended to the array;
    3823              :           otherwise
    3824              : 
    3825              :         - if the containing value is an @ref array, and the token represents a
    3826              :           number, then if the difference between the number and array's size
    3827              :           is smaller than `opts.max_created_elements`, then the size of the
    3828              :           array is increased, so that the number can reference an element in the
    3829              :           array; otherwise
    3830              : 
    3831              :         - if the containing value is of different @ref kind and
    3832              :           `opts.replace_any_scalar` is `true`, or the value is `null`, then
    3833              : 
    3834              :            - if `opts.create_arrays` is `true` and the token either represents
    3835              :              past-the-end marker or a number, then the value is replaced with
    3836              :              an empty array and the token is considered again; otherwise
    3837              : 
    3838              :            - if `opts.create_objects` is `true`, then the value is replaced
    3839              :              with an empty object and the token is considered again; otherwise
    3840              : 
    3841              :         - an error is produced.
    3842              : 
    3843              :         @par Complexity
    3844              :         Linear in the sum of size of `ptr`, size of underlying array, object,
    3845              :         or string and `opts.max_created_elements`.
    3846              : 
    3847              :         @par Exception Safety
    3848              :         Basic guarantee.
    3849              :         Calls to `memory_resource::allocate` may throw.
    3850              : 
    3851              :         @param sv JSON Pointer string.
    3852              : 
    3853              :         @param ref The value to assign to pointed element.
    3854              : 
    3855              :         @param opts The options for the algorithm.
    3856              : 
    3857              :         @return `boost::json::result<value&>` containing either a reference to
    3858              :             the element identified by `ptr` or a corresponding `error_code`.
    3859              : 
    3860              :         @see
    3861              :             @ref set_pointer_options,
    3862              :             [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
    3863              :     */
    3864              :     BOOST_JSON_DECL
    3865              :     system::result<value&>
    3866              :     try_set_at_pointer(
    3867              :         string_view sv,
    3868              :         value_ref ref,
    3869              :         set_pointer_options const& opts = {} );
    3870              : 
    3871              :     /** Set an element via JSON Pointer.
    3872              : 
    3873              :         This function is used to insert or assign to a potentially nested
    3874              :         element of the value using a JSON Pointer string. The function may
    3875              :         create intermediate elements corresponding to pointer segments.
    3876              :         <br/>
    3877              : 
    3878              :         The particular conditions when and what kind of intermediate element
    3879              :         is created is governed by the `ptr` parameter.
    3880              : 
    3881              :         Each pointer token is considered in sequence. For each token
    3882              : 
    3883              :         - if the containing value is an @ref object, then a new `null`
    3884              :         element is created with key equal to unescaped token string; otherwise
    3885              : 
    3886              :         - if the containing value is an @ref array, and the token represents a
    3887              :         past-the-end marker, then a `null` element is appended to the array;
    3888              :         otherwise
    3889              : 
    3890              :         - if the containing value is an @ref array, and the token represents a
    3891              :         number, then if the difference between the number and array's size
    3892              :         is smaller than `opts.max_created_elements`, then the size of the
    3893              :         array is increased, so that the number can reference an element in the
    3894              :         array; otherwise
    3895              : 
    3896              :         - if the containing value is of different @ref kind and
    3897              :           `opts.replace_any_scalar` is `true`, or the value is `null`, then
    3898              : 
    3899              :            - if `opts.create_arrays` is `true` and the token either represents
    3900              :              past-the-end marker or a number, then the value is replaced with
    3901              :              an empty array and the token is considered again; otherwise
    3902              : 
    3903              :            - if `opts.create_objects` is `true`, then the value is replaced
    3904              :              with an empty object and the token is considered again; otherwise
    3905              : 
    3906              :         - an error is produced.
    3907              : 
    3908              :         @par Complexity
    3909              :         Linear in the sum of size of `ptr`, size of underlying array, object,
    3910              :         or string and `opts.max_created_elements`.
    3911              : 
    3912              :         @par Exception Safety
    3913              :         Basic guarantee.
    3914              :         Calls to `memory_resource::allocate` may throw.
    3915              : 
    3916              :         @param sv JSON Pointer string.
    3917              : 
    3918              :         @param ref The value to assign to pointed element.
    3919              : 
    3920              :         @param opts The options for the algorithm.
    3921              : 
    3922              :         @return Reference to the element identified by `ptr`.
    3923              : 
    3924              :         @see @ref set_pointer_options,
    3925              :         <a href="https://datatracker.ietf.org/doc/html/rfc6901">
    3926              :             RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
    3927              :     */
    3928              :     BOOST_JSON_DECL
    3929              :     value&
    3930              :     set_at_pointer(
    3931              :         string_view sv,
    3932              :         value_ref ref,
    3933              :         set_pointer_options const& opts = {} );
    3934              : 
    3935              :     /** Set an element via JSON Pointer.
    3936              : 
    3937              :         This function is used to insert or assign to a potentially nested
    3938              :         element of the value using a JSON Pointer string. The function may
    3939              :         create intermediate elements corresponding to pointer segments.
    3940              :         <br/>
    3941              : 
    3942              :         The particular conditions when and what kind of intermediate element
    3943              :         is created is governed by the `ptr` parameter.
    3944              : 
    3945              :         Each pointer token is considered in sequence. For each token
    3946              : 
    3947              :         - if the containing value is an @ref object, then a new `null`
    3948              :           element is created with key equal to unescaped token string;
    3949              :           otherwise
    3950              : 
    3951              :         - if the containing value is an @ref array, and the token represents a
    3952              :           past-the-end marker, then a `null` element is appended to the array;
    3953              :           otherwise
    3954              : 
    3955              :         - if the containing value is an @ref array, and the token represents a
    3956              :           number, then if the difference between the number and array's size
    3957              :           is smaller than `opts.max_created_elements`, then the size of the
    3958              :           array is increased, so that the number can reference an element in the
    3959              :           array; otherwise
    3960              : 
    3961              :         - if the containing value is of different @ref kind and
    3962              :           `opts.replace_any_scalar` is `true`, or the value is `null`, then
    3963              : 
    3964              :            - if `opts.create_arrays` is `true` and the token either represents
    3965              :              past-the-end marker or a number, then the value is replaced with
    3966              :              an empty array and the token is considered again; otherwise
    3967              : 
    3968              :            - if `opts.create_objects` is `true`, then the value is replaced
    3969              :              with an empty object and the token is considered again; otherwise
    3970              : 
    3971              :         - an error is produced.
    3972              : 
    3973              :         @par Complexity
    3974              :         Linear in the sum of size of `ptr`, size of underlying array, object,
    3975              :         or string and `opts.max_created_elements`.
    3976              : 
    3977              :         @par Exception Safety
    3978              :         Basic guarantee.
    3979              :         Calls to `memory_resource::allocate` may throw.
    3980              : 
    3981              :         @param sv JSON Pointer string.
    3982              : 
    3983              :         @param ref The value to assign to pointed element.
    3984              : 
    3985              :         @param ec Set to the error, if any occurred.
    3986              : 
    3987              :         @param opts The options for the algorithm.
    3988              : 
    3989              :         @return Pointer to the element identified by `ptr`.
    3990              : 
    3991              :         @see @ref set_pointer_options,
    3992              :         <a href="https://datatracker.ietf.org/doc/html/rfc6901">
    3993              :             RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
    3994              :     */
    3995              :     /** @{ */
    3996              :     BOOST_JSON_DECL
    3997              :     value*
    3998              :     set_at_pointer(
    3999              :         string_view sv,
    4000              :         value_ref ref,
    4001              :         system::error_code& ec,
    4002              :         set_pointer_options const& opts = {} );
    4003              : 
    4004              :     BOOST_JSON_DECL
    4005              :     value*
    4006              :     set_at_pointer(
    4007              :         string_view sv,
    4008              :         value_ref ref,
    4009              :         std::error_code& ec,
    4010              :         set_pointer_options const& opts = {} );
    4011              :     /** @} */
    4012              : 
    4013              :     //------------------------------------------------------
    4014              : 
    4015              :     /** Return `true` if two values are equal.
    4016              : 
    4017              :         Two values are equal when they are the
    4018              :         same kind and their referenced values
    4019              :         are equal, or when they are both integral
    4020              :         types and their integral representations
    4021              :         are equal.
    4022              : 
    4023              :         @par Complexity
    4024              :         Constant or linear in the size of
    4025              :         the array, object, or string.
    4026              : 
    4027              :         @par Exception Safety
    4028              :         No-throw guarantee.
    4029              :     */
    4030              :     // inline friend speeds up overload resolution
    4031              :     friend
    4032              :     bool
    4033         4140 :     operator==(
    4034              :         value const& lhs,
    4035              :         value const& rhs) noexcept
    4036              :     {
    4037         4140 :         return lhs.equal(rhs);
    4038              :     }
    4039              : 
    4040              :     /** Return `true` if two values are not equal.
    4041              : 
    4042              :         Two values are equal when they are the
    4043              :         same kind and their referenced values
    4044              :         are equal, or when they are both integral
    4045              :         types and their integral representations
    4046              :         are equal.
    4047              : 
    4048              :         @par Complexity
    4049              :         Constant or linear in the size of
    4050              :         the array, object, or string.
    4051              : 
    4052              :         @par Exception Safety
    4053              :         No-throw guarantee.
    4054              :     */
    4055              :     friend
    4056              :     bool
    4057         3978 :     operator!=(
    4058              :         value const& lhs,
    4059              :         value const& rhs) noexcept
    4060              :     {
    4061         3978 :         return ! (lhs == rhs);
    4062              :     }
    4063              : 
    4064              :     /** Serialize @ref value to an output stream.
    4065              : 
    4066              :         This function serializes a `value` as JSON into the output stream.
    4067              : 
    4068              :         @return Reference to `os`.
    4069              : 
    4070              :         @par Complexity
    4071              :         Constant or linear in the size of `jv`.
    4072              : 
    4073              :         @par Exception Safety
    4074              :         Strong guarantee.
    4075              :         Calls to `memory_resource::allocate` may throw.
    4076              : 
    4077              :         @param os The output stream to serialize to.
    4078              : 
    4079              :         @param jv The value to serialize.
    4080              :     */
    4081              :     BOOST_JSON_DECL
    4082              :     friend
    4083              :     std::ostream&
    4084              :     operator<<(
    4085              :         std::ostream& os,
    4086              :         value const& jv);
    4087              : 
    4088              :     /** Parse @ref value from an input stream.
    4089              : 
    4090              :         This function parses JSON from an input stream into a `value`. If
    4091              :         parsing fails, `std::ios_base::failbit` will be set for `is` and
    4092              :         `jv` will be left unchanged. Regardless of whether `skipws` flag is set
    4093              :         on `is`, consumes whitespace before and after JSON, because whitespace
    4094              :         is considered a part of JSON. Behaves as
    4095              :         [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
    4096              : 
    4097              :         Note: this operator cannot assume that the stream only contains a
    4098              :         single JSON document, which may result in **very underwhelming
    4099              :         performance**, if the stream isn't cooperative. If you know that your
    4100              :         input consists of a single JSON document, consider using @ref parse
    4101              :         function instead.
    4102              : 
    4103              :         @return Reference to `is`.
    4104              : 
    4105              :         @par Complexity
    4106              :         Linear in the size of JSON data.
    4107              : 
    4108              :         @par Exception Safety
    4109              :         Basic guarantee.
    4110              :         Calls to `memory_resource::allocate` may throw.
    4111              :         The stream may throw as configured by
    4112              :         [`std::ios::exceptions`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions).
    4113              : 
    4114              :         @param is The input stream to parse from.
    4115              : 
    4116              :         @param jv The value to parse into.
    4117              : 
    4118              :         @see @ref parse.
    4119              :     */
    4120              :     BOOST_JSON_DECL
    4121              :     friend
    4122              :     std::istream&
    4123              :     operator>>(
    4124              :         std::istream& is,
    4125              :         value& jv);
    4126              : 
    4127              :     /** Helper for `boost::hash` support
    4128              : 
    4129              :         Computes a hash value for `jv`. This function is used by
    4130              :         `boost::hash<value>`. Similar overloads for @ref array, @ref object,
    4131              :         and @ref string do not exist, because those types are supported by
    4132              :         `boost::hash` out of the box.
    4133              : 
    4134              :         @return hash value for `jv`.
    4135              : 
    4136              :         @param jv `value` for which a hash is to be computed.
    4137              : 
    4138              :         @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
    4139              :      */
    4140              : #ifndef BOOST_JSON_DOCS
    4141              :     template<
    4142              :         class T,
    4143              :         typename std::enable_if<
    4144              :             std::is_same< detail::remove_cvref<T>, value >::value >::type*
    4145              :                 = nullptr>
    4146              :     friend
    4147              :     std::size_t
    4148          248 :     hash_value( T const& jv ) noexcept
    4149              : #else
    4150              :     friend
    4151              :     inline
    4152              :     std::size_t
    4153              :     hash_value( value const& jv ) noexcept
    4154              : #endif
    4155              :     {
    4156          248 :         return detail::hash_value_impl(jv);
    4157              :     }
    4158              : 
    4159              : private:
    4160              :     static
    4161              :     void
    4162      2133334 :     relocate(
    4163              :         value* dest,
    4164              :         value const& src) noexcept
    4165              :     {
    4166      2133334 :         std::memcpy(
    4167              :             static_cast<void*>(dest),
    4168              :             &src,
    4169              :             sizeof(src));
    4170      2133334 :     }
    4171              : 
    4172              :     BOOST_JSON_DECL
    4173              :     storage_ptr
    4174              :     destroy() noexcept;
    4175              : 
    4176              :     BOOST_JSON_DECL
    4177              :     bool
    4178              :     equal(value const& other) const noexcept;
    4179              : 
    4180              :     template<class T>
    4181              :     auto
    4182         3311 :     to_number(error& e) const noexcept ->
    4183              :         typename std::enable_if<
    4184              :             std::is_signed<T>::value &&
    4185              :             ! std::is_floating_point<T>::value,
    4186              :                 T>::type
    4187              :     {
    4188         3311 :         if(sca_.k == json::kind::int64)
    4189              :         {
    4190         3232 :             auto const i = sca_.i;
    4191         6458 :             if( i >= (std::numeric_limits<T>::min)() &&
    4192         3226 :                 i <= (std::numeric_limits<T>::max)())
    4193              :             {
    4194         3220 :                 e = {};
    4195         3220 :                 return static_cast<T>(i);
    4196              :             }
    4197           12 :             e = error::not_exact;
    4198              :         }
    4199           79 :         else if(sca_.k == json::kind::uint64)
    4200              :         {
    4201           20 :             auto const u = sca_.u;
    4202           20 :             if(u <= static_cast<std::uint64_t>((
    4203           20 :                 std::numeric_limits<T>::max)()))
    4204              :             {
    4205           10 :                 e = {};
    4206           10 :                 return static_cast<T>(u);
    4207              :             }
    4208           10 :             e = error::not_exact;
    4209              :         }
    4210           59 :         else if(sca_.k == json::kind::double_)
    4211              :         {
    4212           18 :             auto const d = sca_.d;
    4213           18 :             if( d >= static_cast<double>(
    4214           36 :                     (detail::to_number_limit<T>::min)()) &&
    4215              :                 d <= static_cast<double>(
    4216           36 :                     (detail::to_number_limit<T>::max)()) &&
    4217           18 :                 static_cast<T>(d) == d)
    4218              :             {
    4219            8 :                 e = {};
    4220            8 :                 return static_cast<T>(d);
    4221              :             }
    4222           10 :             e = error::not_exact;
    4223              :         }
    4224              :         else
    4225              :         {
    4226           41 :             e = error::not_number;
    4227              :         }
    4228           73 :         return T{};
    4229              :     }
    4230              : 
    4231              :     template<class T>
    4232              :     auto
    4233          109 :     to_number(error& e) const noexcept ->
    4234              :         typename std::enable_if<
    4235              :             std::is_unsigned<T>::value &&
    4236              :             ! std::is_same<T, bool>::value,
    4237              :                 T>::type
    4238              :     {
    4239          109 :         if(sca_.k == json::kind::int64)
    4240              :         {
    4241           44 :             auto const i = sca_.i;
    4242           72 :             if( i >= 0 && static_cast<std::uint64_t>(i) <=
    4243           28 :                 (std::numeric_limits<T>::max)())
    4244              :             {
    4245           22 :                 e = {};
    4246           22 :                 return static_cast<T>(i);
    4247              :             }
    4248           22 :             e = error::not_exact;
    4249              :         }
    4250           65 :         else if(sca_.k == json::kind::uint64)
    4251              :         {
    4252           48 :             auto const u = sca_.u;
    4253           48 :             if(u <= (std::numeric_limits<T>::max)())
    4254              :             {
    4255           42 :                 e = {};
    4256           42 :                 return static_cast<T>(u);
    4257              :             }
    4258            6 :             e = error::not_exact;
    4259              :         }
    4260           17 :         else if(sca_.k == json::kind::double_)
    4261              :         {
    4262           12 :             auto const d = sca_.d;
    4263            8 :             if( d >= 0 &&
    4264           20 :                 d <= (detail::to_number_limit<T>::max)() &&
    4265            8 :                 static_cast<T>(d) == d)
    4266              :             {
    4267            4 :                 e = {};
    4268            4 :                 return static_cast<T>(d);
    4269              :             }
    4270            8 :             e = error::not_exact;
    4271              :         }
    4272              :         else
    4273              :         {
    4274            5 :             e = error::not_number;
    4275              :         }
    4276           41 :         return T{};
    4277              :     }
    4278              : 
    4279              :     template<class T>
    4280              :     auto
    4281           58 :     to_number(error& e) const noexcept ->
    4282              :         typename std::enable_if<
    4283              :             std::is_floating_point<
    4284              :                 T>::value, T>::type
    4285              :     {
    4286           58 :         if(sca_.k == json::kind::int64)
    4287              :         {
    4288           16 :             e = {};
    4289           16 :             return static_cast<T>(sca_.i);
    4290              :         }
    4291           42 :         if(sca_.k == json::kind::uint64)
    4292              :         {
    4293           10 :             e = {};
    4294           10 :             return static_cast<T>(sca_.u);
    4295              :         }
    4296           32 :         if(sca_.k == json::kind::double_)
    4297              :         {
    4298           18 :             e = {};
    4299           18 :             return static_cast<T>(sca_.d);
    4300              :         }
    4301           14 :         e = error::not_number;
    4302           14 :         return {};
    4303              :     }
    4304              : };
    4305              : 
    4306              : // Make sure things are as big as we think they should be
    4307              : #if BOOST_JSON_ARCH == 64
    4308              : BOOST_STATIC_ASSERT(sizeof(value) == 24);
    4309              : #elif BOOST_JSON_ARCH == 32
    4310              : BOOST_STATIC_ASSERT(sizeof(value) == 16);
    4311              : #else
    4312              : # error Unknown architecture
    4313              : #endif
    4314              : 
    4315              : //----------------------------------------------------------
    4316              : 
    4317              : /** A key/value pair.
    4318              : 
    4319              :     This is the type of element used by the @ref object
    4320              :     container.
    4321              : */
    4322              : class key_value_pair
    4323              : {
    4324              : #ifndef BOOST_JSON_DOCS
    4325              :     friend struct detail::access;
    4326              :     using access = detail::access;
    4327              : #endif
    4328              : 
    4329              :     BOOST_JSON_DECL
    4330              :     static char const empty_[1];
    4331              : 
    4332              :     inline
    4333              :     key_value_pair(
    4334              :         pilfered<json::value> k,
    4335              :         pilfered<json::value> v) noexcept;
    4336              : 
    4337              : public:
    4338              :     /// Copy assignment (deleted).
    4339              :     key_value_pair&
    4340              :     operator=(key_value_pair const&) = delete;
    4341              : 
    4342              :     /** Destructor.
    4343              : 
    4344              :         The value is destroyed and all internally
    4345              :         allocated memory is freed.
    4346              :     */
    4347        58814 :     ~key_value_pair() noexcept
    4348        52181 :     {
    4349        58814 :         auto const& sp = value_.storage();
    4350        58814 :         if(sp.is_not_shared_and_deallocate_is_trivial())
    4351            0 :             return;
    4352        58814 :         if(key_ == empty_)
    4353         6633 :             return;
    4354        52181 :         sp->deallocate(const_cast<char*>(key_),
    4355        52181 :             len_ + 1, alignof(char));
    4356        58814 :     }
    4357              : 
    4358              :     /** Copy constructor.
    4359              : 
    4360              :         This constructs a key/value pair with a
    4361              :         copy of another key/value pair, using
    4362              :         the same memory resource as `other`.
    4363              : 
    4364              :         @par Exception Safety
    4365              :         Strong guarantee.
    4366              :         Calls to `memory_resource::allocate` may throw.
    4367              : 
    4368              :         @param other The key/value pair to copy.
    4369              :     */
    4370          758 :     key_value_pair(
    4371              :         key_value_pair const& other)
    4372          758 :         : key_value_pair(other,
    4373          758 :             other.storage())
    4374              :     {
    4375          758 :     }
    4376              : 
    4377              :     /** Copy constructor.
    4378              : 
    4379              :         This constructs a key/value pair with a
    4380              :         copy of another key/value pair, using
    4381              :         the specified memory resource.
    4382              : 
    4383              :         @par Exception Safety
    4384              :         Strong guarantee.
    4385              :         Calls to `memory_resource::allocate` may throw.
    4386              : 
    4387              :         @param other The key/value pair to copy.
    4388              : 
    4389              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
    4390              :         use. The element will acquire shared ownership of the memory resource.
    4391              :     */
    4392              :     BOOST_JSON_DECL
    4393              :     key_value_pair(
    4394              :         key_value_pair const& other,
    4395              :         storage_ptr sp);
    4396              : 
    4397              :     /** Move constructor.
    4398              : 
    4399              :         The pair is constructed by acquiring
    4400              :         ownership of the contents of `other` and
    4401              :         shared ownership of `other`'s memory resource.
    4402              : 
    4403              :         @note
    4404              : 
    4405              :         After construction, the moved-from pair holds an
    4406              :         empty key, and a null value with its current
    4407              :         storage pointer.
    4408              : 
    4409              :         @par Complexity
    4410              :         Constant.
    4411              : 
    4412              :         @par Exception Safety
    4413              :         No-throw guarantee.
    4414              : 
    4415              :         @param other The pair to move.
    4416              :     */
    4417            1 :     key_value_pair(
    4418              :         key_value_pair&& other) noexcept
    4419            1 :         : value_(std::move(other.value_))
    4420            2 :         , key_(detail::exchange(
    4421            1 :             other.key_, empty_))
    4422            2 :         , len_(detail::exchange(
    4423            1 :             other.len_, 0))
    4424              :     {
    4425            1 :     }
    4426              : 
    4427              :     /** Pilfer constructor.
    4428              : 
    4429              :         The pair is constructed by acquiring ownership
    4430              :         of the contents of `other` using pilfer semantics.
    4431              :         This is more efficient than move construction, when
    4432              :         it is known that the moved-from object will be
    4433              :         immediately destroyed afterwards.
    4434              : 
    4435              :         @par Complexity
    4436              :         Constant.
    4437              : 
    4438              :         @par Exception Safety
    4439              :         No-throw guarantee.
    4440              : 
    4441              :         @param other The value to pilfer. After pilfer
    4442              :         construction, `other` is not in a usable state
    4443              :         and may only be destroyed.
    4444              : 
    4445              :         @see @ref pilfer,
    4446              :             <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
    4447              :                 Valueless Variants Considered Harmful</a>
    4448              :     */
    4449         6632 :     key_value_pair(
    4450              :         pilfered<key_value_pair> other) noexcept
    4451         6632 :         : value_(pilfer(other.get().value_))
    4452        13264 :         , key_(detail::exchange(
    4453         6632 :             other.get().key_, empty_))
    4454        13264 :         , len_(detail::exchange(
    4455         6632 :             other.get().len_, 0))
    4456              :     {
    4457         6632 :     }
    4458              : 
    4459              :     /** Constructor.
    4460              : 
    4461              :         This constructs a key/value pair.
    4462              : 
    4463              :         @par Exception Safety
    4464              :         Strong guarantee.
    4465              :         Calls to `memory_resource::allocate` may throw.
    4466              : 
    4467              :         @param key The key string to use.
    4468              : 
    4469              :         @param args Optional arguments forwarded to
    4470              :         the @ref value constructor.
    4471              :     */
    4472              :     template<class... Args>
    4473              :     explicit
    4474         7765 :     key_value_pair(
    4475              :         string_view key,
    4476              :         Args&&... args)
    4477         7766 :         : value_(std::forward<Args>(args)...)
    4478              :     {
    4479         7764 :         if(key.size() > string::max_size())
    4480              :         {
    4481              :             BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
    4482            1 :             detail::throw_system_error( error::key_too_large, &loc );
    4483              :         }
    4484              :         auto s = reinterpret_cast<
    4485         7763 :             char*>(value_.storage()->
    4486         7763 :                 allocate(key.size() + 1, alignof(char)));
    4487         7457 :         std::memcpy(s, key.data(), key.size());
    4488         7457 :         s[key.size()] = 0;
    4489         7457 :         key_ = s;
    4490         7457 :         len_ = static_cast<
    4491         7457 :             std::uint32_t>(key.size());
    4492         7764 :     }
    4493              : 
    4494              :     /** Constructor.
    4495              : 
    4496              :         This constructs a key/value pair. A
    4497              :         copy of the specified value is made,
    4498              :         using the specified memory resource.
    4499              : 
    4500              :         @par Exception Safety
    4501              :         Strong guarantee.
    4502              :         Calls to `memory_resource::allocate` may throw.
    4503              : 
    4504              :         @param p A `std::pair` with the key
    4505              :             string and @ref value to construct with.
    4506              : 
    4507              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
    4508              :         use. The element will acquire shared ownership of the memory resource.
    4509              :     */
    4510              :     explicit
    4511            0 :     key_value_pair(
    4512              :         std::pair<
    4513              :             string_view,
    4514              :             json::value> const& p,
    4515              :         storage_ptr sp = {})
    4516            0 :         : key_value_pair(
    4517              :             p.first,
    4518            0 :             p.second,
    4519            0 :             std::move(sp))
    4520              :     {
    4521            0 :     }
    4522              : 
    4523              :     /** Constructor.
    4524              : 
    4525              :         This constructs a key/value pair.
    4526              :         Ownership of the specified value is
    4527              :         transferred by move construction.
    4528              : 
    4529              :         @par Exception Safety
    4530              :         Strong guarantee.
    4531              :         Calls to `memory_resource::allocate` may throw.
    4532              : 
    4533              :         @param p A `std::pair` with the key
    4534              :             string and @ref value to construct with.
    4535              : 
    4536              :         @param sp A pointer to the `boost::container::pmr::memory_resource` to
    4537              :         use. The element will acquire shared ownership of the memory resource.
    4538              :     */
    4539              :     explicit
    4540         3125 :     key_value_pair(
    4541              :         std::pair<
    4542              :             string_view,
    4543              :             json::value>&& p,
    4544              :         storage_ptr sp = {})
    4545         3125 :         : key_value_pair(
    4546              :             p.first,
    4547         3125 :             std::move(p).second,
    4548         6250 :             std::move(sp))
    4549              :     {
    4550         2978 :     }
    4551              : 
    4552              :     /** Return the associated memory resource.
    4553              : 
    4554              :         This returns a pointer to the memory
    4555              :         resource used to construct the value.
    4556              : 
    4557              :         @par Complexity
    4558              :         Constant.
    4559              : 
    4560              :         @par Exception Safety
    4561              :         No-throw guarantee.
    4562              :     */
    4563              :     storage_ptr const&
    4564          758 :     storage() const noexcept
    4565              :     {
    4566          758 :         return value_.storage();
    4567              :     }
    4568              : 
    4569              :     /** Return the key of this element.
    4570              : 
    4571              :         After construction, the key may
    4572              :         not be modified.
    4573              : 
    4574              :         @par Complexity
    4575              :         Constant.
    4576              : 
    4577              :         @par Exception Safety
    4578              :         No-throw guarantee.
    4579              :     */
    4580              :     string_view const
    4581       160902 :     key() const noexcept
    4582              :     {
    4583       160902 :         return { key_, len_ };
    4584              :     }
    4585              : 
    4586              :     /** Return the key of this element as a null-terminated string.
    4587              : 
    4588              :         @par Complexity
    4589              :         Constant.
    4590              : 
    4591              :         @par Exception Safety
    4592              :         No-throw guarantee.
    4593              :     */
    4594              :     char const*
    4595            1 :     key_c_str() const noexcept
    4596              :     {
    4597            1 :         return key_;
    4598              :     }
    4599              : 
    4600              :     /** Return the value of this element.
    4601              : 
    4602              :         @par Complexity
    4603              :         Constant.
    4604              : 
    4605              :         @par Exception Safety
    4606              :         No-throw guarantee.
    4607              :     */
    4608              :     /** @{ */
    4609              :     json::value const&
    4610        64839 :     value() const& noexcept
    4611              :     {
    4612        64839 :         return value_;
    4613              :     }
    4614              : 
    4615              :     json::value&&
    4616              :     value() && noexcept
    4617              :     {
    4618              :         return std::move( value() );
    4619              :     }
    4620              : 
    4621              :     json::value&
    4622          944 :     value() & noexcept
    4623              :     {
    4624          944 :         return value_;
    4625              :     }
    4626              :     /** @} */
    4627              : 
    4628              : private:
    4629              :     json::value value_;
    4630              :     char const* key_;
    4631              :     std::uint32_t len_;
    4632              :     std::uint32_t next_;
    4633              : };
    4634              : 
    4635              : //----------------------------------------------------------
    4636              : 
    4637              : #ifdef BOOST_JSON_DOCS
    4638              : 
    4639              : /** Tuple-like element access.
    4640              : 
    4641              :     This overload permits the key and value
    4642              :     of a `key_value_pair` to be accessed
    4643              :     by index. For example:
    4644              : 
    4645              :     @code
    4646              : 
    4647              :     key_value_pair kvp("num", 42);
    4648              : 
    4649              :     string_view key = get<0>(kvp);
    4650              :     value& jv = get<1>(kvp);
    4651              : 
    4652              :     @endcode
    4653              : 
    4654              :     @par Structured Bindings
    4655              : 
    4656              :     When using C++17 or greater, objects of type
    4657              :     @ref key_value_pair may be used to initialize
    4658              :     structured bindings:
    4659              : 
    4660              :     @code
    4661              : 
    4662              :     key_value_pair kvp("num", 42);
    4663              : 
    4664              :     auto& [key, value] = kvp;
    4665              : 
    4666              :     @endcode
    4667              : 
    4668              :     Depending on the value of `I`, the return type will be:
    4669              : 
    4670              :     @li `string_view const` if `I == 0`, or
    4671              : 
    4672              :     @li `value&`, `value const&`, or `value&&` if `I == 1`.
    4673              : 
    4674              :     Any other value for `I` is ill-formed.
    4675              : 
    4676              :     @tparam I The element index to access.
    4677              : 
    4678              :     @par Constraints
    4679              : 
    4680              :     `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
    4681              : 
    4682              :     @return `kvp.key()` if `I == 0`, or `kvp.value()`
    4683              :     if `I == 1`.
    4684              : 
    4685              :     @param kvp The @ref key_value_pair object
    4686              :     to access.
    4687              : */
    4688              : template<
    4689              :     std::size_t I,
    4690              :     class T>
    4691              : __see_below__
    4692              : get(T&& kvp) noexcept;
    4693              : 
    4694              : #else
    4695              : 
    4696              : template<std::size_t I>
    4697              : auto
    4698              : get(key_value_pair const&) noexcept ->
    4699              :     typename std::conditional<I == 0,
    4700              :         string_view const,
    4701              :         value const&>::type
    4702              : {
    4703              :     static_assert(I == 0,
    4704              :         "key_value_pair index out of range");
    4705              : }
    4706              : 
    4707              : template<std::size_t I>
    4708              : auto
    4709              : get(key_value_pair&) noexcept ->
    4710              :     typename std::conditional<I == 0,
    4711              :         string_view const,
    4712              :         value&>::type
    4713              : {
    4714              :     static_assert(I == 0,
    4715              :         "key_value_pair index out of range");
    4716              : }
    4717              : 
    4718              : template<std::size_t I>
    4719              : auto
    4720              : get(key_value_pair&&) noexcept ->
    4721              :     typename std::conditional<I == 0,
    4722              :         string_view const,
    4723              :         value&&>::type
    4724              : {
    4725              :     static_assert(I == 0,
    4726              :         "key_value_pair index out of range");
    4727              : }
    4728              : 
    4729              : /** Extracts a key_value_pair's key using tuple-like interface
    4730              : */
    4731              : template<>
    4732              : inline
    4733              : string_view const
    4734           50 : get<0>(key_value_pair const& kvp) noexcept
    4735              : {
    4736           50 :     return kvp.key();
    4737              : }
    4738              : 
    4739              : /** Extracts a key_value_pair's key using tuple-like interface
    4740              : */
    4741              : template<>
    4742              : inline
    4743              : string_view const
    4744            7 : get<0>(key_value_pair& kvp) noexcept
    4745              : {
    4746            7 :     return kvp.key();
    4747              : }
    4748              : 
    4749              : /** Extracts a key_value_pair's key using tuple-like interface
    4750              : */
    4751              : template<>
    4752              : inline
    4753              : string_view const
    4754              : get<0>(key_value_pair&& kvp) noexcept
    4755              : {
    4756              :     return kvp.key();
    4757              : }
    4758              : 
    4759              : /** Extracts a key_value_pair's value using tuple-like interface
    4760              : */
    4761              : template<>
    4762              : inline
    4763              : value const&
    4764           50 : get<1>(key_value_pair const& kvp) noexcept
    4765              : {
    4766           50 :     return kvp.value();
    4767              : }
    4768              : 
    4769              : /** Extracts a key_value_pair's value using tuple-like interface
    4770              : */
    4771              : template<>
    4772              : inline
    4773              : value&
    4774            7 : get<1>(key_value_pair& kvp) noexcept
    4775              : {
    4776            7 :     return kvp.value();
    4777              : }
    4778              : 
    4779              : /** Extracts a key_value_pair's value using tuple-like interface
    4780              : */
    4781              : template<>
    4782              : inline
    4783              : value&&
    4784              : get<1>(key_value_pair&& kvp) noexcept
    4785              : {
    4786              :     return std::move(kvp.value());
    4787              : }
    4788              : 
    4789              : #endif
    4790              : 
    4791              : } // namespace json
    4792              : } // namespace boost
    4793              : 
    4794              : #ifdef __clang__
    4795              : # pragma clang diagnostic push
    4796              : # pragma clang diagnostic ignored "-Wmismatched-tags"
    4797              : #endif
    4798              : 
    4799              : #ifndef BOOST_JSON_DOCS
    4800              : 
    4801              : namespace std {
    4802              : 
    4803              : /** Tuple-like size access for key_value_pair
    4804              : */
    4805              : template<>
    4806              : struct tuple_size< ::boost::json::key_value_pair >
    4807              :     : std::integral_constant<std::size_t, 2>
    4808              : {
    4809              : };
    4810              : 
    4811              : /** Tuple-like access for the key type of key_value_pair
    4812              : */
    4813              : template<>
    4814              : struct tuple_element<0, ::boost::json::key_value_pair>
    4815              : {
    4816              :     using type = ::boost::json::string_view const;
    4817              : };
    4818              : 
    4819              : /** Tuple-like access for the value type of key_value_pair
    4820              : */
    4821              : template<>
    4822              : struct tuple_element<1, ::boost::json::key_value_pair>
    4823              : {
    4824              :     using type = ::boost::json::value&;
    4825              : };
    4826              : 
    4827              : /** Tuple-like access for the value type of key_value_pair
    4828              : */
    4829              : template<>
    4830              : struct tuple_element<1, ::boost::json::key_value_pair const>
    4831              : {
    4832              :     using type = ::boost::json::value const&;
    4833              : };
    4834              : 
    4835              : } // std
    4836              : 
    4837              : #endif
    4838              : 
    4839              : // std::hash specialization
    4840              : #ifndef BOOST_JSON_DOCS
    4841              : namespace std {
    4842              : template <>
    4843              : struct hash< ::boost::json::value > {
    4844              :     BOOST_JSON_DECL
    4845              :     std::size_t
    4846              :     operator()(::boost::json::value const& jv) const noexcept;
    4847              : };
    4848              : } // std
    4849              : #endif
    4850              : 
    4851              : 
    4852              : #ifdef __clang__
    4853              : # pragma clang diagnostic pop
    4854              : #endif
    4855              : 
    4856              : // These are here because value, array,
    4857              : // and object form cyclic references.
    4858              : 
    4859              : #include <boost/json/detail/impl/array.hpp>
    4860              : #include <boost/json/impl/array.hpp>
    4861              : #include <boost/json/impl/object.hpp>
    4862              : #include <boost/json/impl/value.hpp>
    4863              : 
    4864              : // These must come after array and object
    4865              : #include <boost/json/impl/value_ref.hpp>
    4866              : 
    4867              : #endif
        

Generated by: LCOV version 2.1