LCOV - code coverage report
Current view: top level - json - value_ref.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 114 114
Test Date: 2026-02-25 20:43:10 Functions: 98.2 % 57 56 1

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/boostorg/json
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_JSON_VALUE_REF_HPP
      11                 : #define BOOST_JSON_VALUE_REF_HPP
      12                 : 
      13                 : #include <boost/json/detail/config.hpp>
      14                 : #include <boost/json/storage_ptr.hpp>
      15                 : #include <boost/json/string.hpp>
      16                 : #include <initializer_list>
      17                 : #include <type_traits>
      18                 : #include <utility>
      19                 : 
      20                 : namespace boost {
      21                 : namespace json {
      22                 : 
      23                 : #ifndef BOOST_JSON_DOCS
      24                 : class value;
      25                 : class object;
      26                 : class array;
      27                 : class string;
      28                 : #endif
      29                 : 
      30                 : //----------------------------------------------------------
      31                 : 
      32                 : /** The type used in initializer lists.
      33                 : 
      34                 :     This type is used in initializer lists for lazy construction of and
      35                 :     assignment to the container types @ref value, @ref array, and @ref object.
      36                 :     The two types of initializer lists used are:
      37                 : 
      38                 :     @li `std::initializer_list< value_ref >` for constructing or assigning
      39                 :         a @ref value or @ref array, and
      40                 :     @li `std::initializer_list< std::pair< string_view, value_ref > >` for
      41                 :         constructing or assigning an @ref object.
      42                 : 
      43                 :     A `value_ref` uses reference semantics. Creation of the actual container
      44                 :     from the initializer list is lazily deferred until the list is used. This
      45                 :     means that the @ref boost::container::pmr::memory_resource used to
      46                 :     construct a container can be specified after the point where the
      47                 :     initializer list is specified. Also, the usage of this type allows to avoid
      48                 :     constructing a @ref value until it's necessary.
      49                 : 
      50                 :     @par Example
      51                 :     This example demonstrates how a user-defined type containing a JSON value
      52                 :     can be constructed from an initializer list:
      53                 : 
      54                 :     @code
      55                 :     class my_type
      56                 :     {
      57                 :         value jv_;
      58                 : 
      59                 :     public:
      60                 :         my_type( std::initializer_list<value_ref> init )
      61                 :             : jv_(init)
      62                 :         {
      63                 :         }
      64                 :     };
      65                 :     @endcode
      66                 : 
      67                 :     @warning `value_ref` does not take ownership of the objects it was
      68                 :     constructed with. If those objects' lifetimes end before the `value_ref`
      69                 :     object is used, you will get undefined behavior. Because of this it is
      70                 :     advised against declaring a variable of type
      71                 :     `std::initializer_list<value_ref>` except in function parameter lists.
      72                 : 
      73                 :     @see @ref value, @ref array, @ref object, @ref value::set_at_pointer.
      74                 : */
      75                 : class value_ref
      76                 : {
      77                 :     friend class value;
      78                 :     friend class object;
      79                 :     friend class array;
      80                 : 
      81                 :     friend class value_ref_test;
      82                 : 
      83                 :     enum class what
      84                 :     {
      85                 :         str,
      86                 :         ini,
      87                 :         func,
      88                 :         cfunc,
      89                 :         strfunc,
      90                 :     };
      91                 : 
      92                 :     using init_list =
      93                 :         std::initializer_list<value_ref>;
      94                 : 
      95                 :     struct func_type
      96                 :     {
      97                 :         value(*f)(void*, storage_ptr);
      98                 :         void* p;
      99                 :     };
     100                 : 
     101                 :     struct cfunc_type
     102                 :     {
     103                 :         value(*f)(void const*, storage_ptr);
     104                 :         void const* p;
     105                 :     };
     106                 : 
     107                 :     union arg_type
     108                 :     {
     109                 :         string_view         str_;
     110                 :         init_list           init_list_;
     111                 : 
     112                 :         signed char         schar_;
     113                 :         short               short_;
     114                 :         int                 int_;
     115                 :         long                long_;
     116                 :         long long           long_long_;
     117                 :         unsigned char       uchar_;
     118                 :         unsigned short      ushort_;
     119                 :         unsigned int        uint_;
     120                 :         unsigned long       ulong_;
     121                 :         unsigned long long  ulong_long_;
     122                 :         float               float_;
     123                 :         double              double_;
     124                 :         bool                bool_;
     125                 :         std::nullptr_t      nullptr_;
     126                 : 
     127 HIT         101 :         arg_type() {}
     128             917 :         explicit arg_type(string_view t) noexcept : str_(t) {}
     129             659 :         explicit arg_type(init_list t) noexcept : init_list_(t) {}
     130               1 :         explicit arg_type(signed char t) noexcept : schar_(t) {}
     131               3 :         explicit arg_type(short t) noexcept : short_(t) {}
     132            2722 :         explicit arg_type(int t) noexcept : int_(t) {}
     133               3 :         explicit arg_type(long t) noexcept : long_(t) {}
     134               3 :         explicit arg_type(long long t) noexcept : long_long_(t) {}
     135              21 :         explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
     136               3 :         explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
     137              45 :         explicit arg_type(unsigned int t) noexcept : uint_(t) {}
     138               3 :         explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
     139               3 :         explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
     140              18 :         explicit arg_type(float t) noexcept : float_(t) {}
     141              34 :         explicit arg_type(double t) noexcept : double_(t) {}
     142             288 :         explicit arg_type(bool t) noexcept : bool_(t) {}
     143              88 :         explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
     144                 :     };
     145                 : 
     146                 :     arg_type arg_;
     147                 : #ifndef BOOST_JSON_DOCS
     148                 :     // VFALCO doc toolchain erroneously
     149                 :     // displays private, anonymous unions as public
     150                 :     union
     151                 :     {
     152                 :         func_type f_;
     153                 :         cfunc_type cf_;
     154                 :     };
     155                 : #endif
     156                 :     what what_;
     157                 : 
     158                 : public:
     159                 :     /** Constructors.
     160                 : 
     161                 :         @li **(1)** copy constructor.
     162                 :         @li **(2)** move constructor.
     163                 :         @li **(3)** the constructed value stores a reference to `t`'s character
     164                 :             array.
     165                 :         @li **(4)** the constructed value stores a `const` reference to `t`.
     166                 :         @li **(5)** the constructed value stores an rvalue reference to `t`.
     167                 :         @li **(6)** the constructed value stores a copy of `b`.
     168                 :         @li **(7)**--**(18)** the constructed value stores a copy of `t`.
     169                 :         @li **(19)** the constrcuted value stores `nullptr`.
     170                 :         @li **(20)** the constrcuted value stores a copy of `init`.
     171                 : 
     172                 :         In addition the constructed object stores a pointer to a function that
     173                 :         captures the type information necessary to construct a @ref value from
     174                 :         the stored data.
     175                 : 
     176                 :         @warning The overloads that accept references do not take ownership of
     177                 :         referenced objects. The caller is responsible for making sure those
     178                 :         objects do not go out of scope before the `value_ref` object is used.
     179                 :         It is advised you only use `value_ref` (or any type that contains a
     180                 :         `value_ref` subobject) as function parameters or take special care to
     181                 :         not invoke undefeined behavior.
     182                 : 
     183                 :         @par Complexity
     184                 :         @li **(1)**--**(19)** constant.
     185                 :         @li **(20)** linear in `init.size()`.
     186                 : 
     187                 :         @par Exception Safety
     188                 :         No-throw guarantee.
     189                 : 
     190                 :         @{
     191                 :     */
     192                 :     value_ref(
     193                 :         value_ref const&) = default;
     194                 : 
     195                 :     /// Overload
     196                 :     value_ref(
     197                 :         value_ref&&) = default;
     198                 : 
     199                 :     /// Overload
     200                 : #ifdef BOOST_JSON_DOCS
     201                 :     value_ref(string_view s) noexcept;
     202                 : #else
     203                 :     template<
     204                 :         class T
     205                 :         ,class = typename
     206                 :             std::enable_if<
     207                 :                 std::is_constructible<
     208                 :                     string_view, T>::value>::type
     209                 :     >
     210             917 :     value_ref(
     211                 :         T const& t) noexcept
     212             917 :         : arg_(string_view(t))
     213             917 :         , what_(what::str)
     214                 :     {
     215             917 :     }
     216                 : #endif
     217                 : 
     218                 :     /// Overload
     219                 :     template<class T>
     220              22 :     value_ref(
     221                 :         T const& t
     222                 : #ifndef BOOST_JSON_DOCS
     223                 :         ,typename std::enable_if<
     224                 :             ! std::is_constructible<
     225                 :                 string_view, T>::value &&
     226                 :             ! std::is_same<bool, T>::value
     227                 :                 >::type* = 0
     228                 : #endif
     229                 :         ) noexcept
     230              22 :         : cf_{&from_const<T>, &t}
     231              22 :         , what_(what::cfunc)
     232                 :     {
     233              22 :     }
     234                 : 
     235                 :     /// Overload
     236                 :     template<class T>
     237              79 :     value_ref(
     238                 :         T&& t
     239                 : #ifndef BOOST_JSON_DOCS
     240                 :         ,typename std::enable_if<
     241                 :             (! std::is_constructible<
     242                 :                 string_view, T>::value ||
     243                 :             std::is_same<string, T>::value) &&
     244                 :             ! std::is_same<bool,
     245                 :                 detail::remove_cvref<T>>::value &&
     246                 :             std::is_same<T, detail::remove_cvref<T>>
     247                 :                 ::value>::type* = 0
     248                 : #endif
     249                 :         ) noexcept
     250              79 :         : f_{&from_rvalue<
     251                 :             detail::remove_cvref<T>>, &t}
     252              79 :         , what_(std::is_same<string, T>::value ?
     253              79 :                 what::strfunc : what::func)
     254                 :     {
     255              79 :     }
     256                 : 
     257                 :     /// Overload
     258                 : #ifdef BOOST_JSON_DOCS
     259                 :     value_ref(bool b) noexcept;
     260                 : #else
     261                 :     template<
     262                 :         class T
     263                 :         ,class = typename std::enable_if<
     264                 :             std::is_same<T, bool>::value>::type
     265                 :     >
     266             288 :     value_ref(
     267                 :         T b) noexcept
     268             288 :         : arg_(b)
     269             288 :         , cf_{&from_builtin<bool>, &arg_.bool_}
     270             288 :         , what_(what::cfunc)
     271                 :     {
     272             288 :     }
     273                 : #endif
     274                 : 
     275                 :     /// Overload
     276               1 :     value_ref(signed char t) noexcept
     277               1 :         : arg_(t)
     278               1 :         , cf_{&from_builtin<signed char>, &arg_.schar_}
     279               1 :         , what_(what::cfunc)
     280                 :     {
     281               1 :     }
     282                 : 
     283                 :     /// Overload
     284               3 :     value_ref(short t) noexcept
     285               3 :         : arg_(t)
     286               3 :         , cf_{&from_builtin<short>, &arg_.short_}
     287               3 :         , what_(what::cfunc)
     288                 :     {
     289               3 :     }
     290                 : 
     291                 :     /// Overload
     292            2722 :     value_ref(int t) noexcept
     293            2722 :         : arg_(t)
     294            2722 :         , cf_{&from_builtin<int>, &arg_.int_}
     295            2722 :         , what_(what::cfunc)
     296                 :     {
     297            2722 :     }
     298                 : 
     299                 :     /// Overload
     300               3 :     value_ref(long t) noexcept
     301               3 :         : arg_(t)
     302               3 :         , cf_{&from_builtin<
     303               3 :             long>, &arg_.long_}
     304               3 :         , what_(what::cfunc)
     305                 :     {
     306               3 :     }
     307                 : 
     308                 :     /// Overload
     309               3 :     value_ref(long long t) noexcept
     310               3 :         : arg_(t)
     311               3 :         , cf_{&from_builtin<
     312               3 :             long long>, &arg_.long_long_}
     313               3 :         , what_(what::cfunc)
     314                 :     {
     315               3 :     }
     316                 : 
     317                 :     /// Overload
     318              21 :     value_ref(unsigned char t) noexcept
     319              21 :         : arg_(t)
     320              21 :         , cf_{&from_builtin<
     321              21 :             unsigned char>, &arg_.uchar_}
     322              21 :         , what_(what::cfunc)
     323                 :     {
     324              21 :     }
     325                 : 
     326                 :     /// Overload
     327               3 :     value_ref(unsigned short t) noexcept
     328               3 :         : arg_(t)
     329               3 :         , cf_{&from_builtin<
     330               3 :             unsigned short>, &arg_.ushort_}
     331               3 :         , what_(what::cfunc)
     332                 :     {
     333               3 :     }
     334                 : 
     335                 :     /// Overload
     336              45 :     value_ref(unsigned int t) noexcept
     337              45 :         : arg_(t)
     338              45 :         , cf_{&from_builtin<
     339              45 :             unsigned int>, &arg_.uint_}
     340              45 :         , what_(what::cfunc)
     341                 :     {
     342              45 :     }
     343                 : 
     344                 :     /// Overload
     345               3 :     value_ref(unsigned long t) noexcept
     346               3 :         : arg_(t)
     347               3 :         , cf_{&from_builtin<
     348               3 :             unsigned long>, &arg_.ulong_}
     349               3 :         , what_(what::cfunc)
     350                 :     {
     351               3 :     }
     352                 : 
     353                 :     /// Overload
     354               3 :     value_ref(unsigned long long t) noexcept
     355               3 :         : arg_(t)
     356               3 :         , cf_{&from_builtin<
     357               3 :             unsigned long long>, &arg_.ulong_long_}
     358               3 :         , what_(what::cfunc)
     359                 :     {
     360               3 :     }
     361                 : 
     362                 :     /// Overload
     363              18 :     value_ref(float t) noexcept
     364              18 :         : arg_(t)
     365              18 :         , cf_{&from_builtin<
     366              18 :             float>, &arg_.float_}
     367              18 :         , what_(what::cfunc)
     368                 :     {
     369              18 :     }
     370                 : 
     371                 :     /// Overload
     372              34 :     value_ref(double t) noexcept
     373              34 :         : arg_(t)
     374              34 :         , cf_{&from_builtin<
     375              34 :             double>, &arg_.double_}
     376              34 :         , what_(what::cfunc)
     377                 :     {
     378              34 :     }
     379                 : 
     380                 :     /// Overload
     381              88 :     value_ref(std::nullptr_t) noexcept
     382              88 :         : arg_(nullptr)
     383              88 :         , cf_{&from_builtin<
     384              88 :             std::nullptr_t>, &arg_.nullptr_}
     385              88 :         , what_(what::cfunc)
     386                 :     {
     387              88 :     }
     388                 : 
     389                 :     /// Overload
     390             659 :     value_ref(
     391                 :         std::initializer_list<value_ref> init) noexcept
     392             659 :         : arg_(init)
     393             659 :         , what_(what::ini)
     394                 :     {
     395             659 :     }
     396                 : 
     397                 :     /// @}
     398                 : 
     399                 : #ifndef BOOST_JSON_DOCS
     400                 : // Not public
     401                 : //private:
     402                 :     // VFALCO Why is this needed?
     403                 :     /** Operator conversion to @ref value
     404                 : 
     405                 :         This allows creation of a @ref value from
     406                 :         an initializer list element.
     407                 :     */
     408                 :     BOOST_JSON_DECL
     409                 :     operator value() const;
     410                 : #endif
     411                 : 
     412                 : private:
     413                 :     template<class T>
     414                 :     static
     415                 :     value
     416                 :     from_builtin(
     417                 :         void const* p,
     418                 :         storage_ptr sp) noexcept;
     419                 : 
     420                 :     template<class T>
     421                 :     static
     422                 :     value
     423                 :     from_const(
     424                 :         void const* p,
     425                 :         storage_ptr sp);
     426                 : 
     427                 :     template<class T>
     428                 :     static
     429                 :     value
     430                 :     from_rvalue(
     431                 :         void* p,
     432                 :         storage_ptr sp);
     433                 : 
     434                 :     static
     435                 :     BOOST_JSON_DECL
     436                 :     value
     437                 :     from_init_list(
     438                 :         void const* p,
     439                 :         storage_ptr sp);
     440                 : 
     441                 :     inline
     442                 :     bool
     443                 :     is_key_value_pair() const noexcept;
     444                 : 
     445                 :     static
     446                 :     inline
     447                 :     bool
     448                 :     maybe_object(
     449                 :         std::initializer_list<
     450                 :             value_ref> init) noexcept;
     451                 : 
     452                 :     inline
     453                 :     string_view
     454                 :     get_string() const noexcept;
     455                 : 
     456                 :     BOOST_JSON_DECL
     457                 :     value
     458                 :     make_value(
     459                 :         storage_ptr sp) const;
     460                 : 
     461                 :     BOOST_JSON_DECL
     462                 :     static
     463                 :     value
     464                 :     make_value(
     465                 :         std::initializer_list<
     466                 :             value_ref> init,
     467                 :         storage_ptr sp);
     468                 : 
     469                 :     BOOST_JSON_DECL
     470                 :     static
     471                 :     object
     472                 :     make_object(
     473                 :         std::initializer_list<value_ref> init,
     474                 :         storage_ptr sp);
     475                 : 
     476                 :     BOOST_JSON_DECL
     477                 :     static
     478                 :     array
     479                 :     make_array(
     480                 :         std::initializer_list<
     481                 :             value_ref> init,
     482                 :         storage_ptr sp);
     483                 : 
     484                 :     BOOST_JSON_DECL
     485                 :     static
     486                 :     void
     487                 :     write_array(
     488                 :         value* dest,
     489                 :         std::initializer_list<
     490                 :             value_ref> init,
     491                 :         storage_ptr const& sp);
     492                 : };
     493                 : 
     494                 : } // namespace json
     495                 : } // namespace boost
     496                 : 
     497                 : // Must be included here for this file to stand alone
     498                 : #include <boost/json/value.hpp>
     499                 : 
     500                 : // includes are at the bottom of <boost/json/value.hpp>
     501                 : //#include <boost/json/impl/value.hpp>
     502                 : //#include <boost/json/impl/value.ipp>
     503                 : 
     504                 : #endif
        

Generated by: LCOV version 2.3