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:20:51 Functions: 98.0 % 196 192

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

Generated by: LCOV version 2.1