LCOV - code coverage report
Current view: top level - json - value.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 98.9 % 522 516 6
Test Date: 2026-02-25 20:43:10 Functions: 98.0 % 196 192 4

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

Generated by: LCOV version 2.3