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

Generated by: LCOV version 2.3