LCOV - code coverage report
Current view: top level - json - value_ref.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 114 114
Test Date: 2025-12-23 17:38:56 Functions: 96.4 % 56 54

            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           98 :         arg_type() {}
     128          912 :         explicit arg_type(string_view t) noexcept : str_(t) {}
     129          656 :         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         2692 :         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          287 :         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          912 :     value_ref(
     211              :         T const& t) noexcept
     212          912 :         : arg_(string_view(t))
     213          912 :         , what_(what::str)
     214              :     {
     215          912 :     }
     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           76 :     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           76 :         : f_{&from_rvalue<
     251              :             detail::remove_cvref<T>>, &t}
     252           76 :         , what_(std::is_same<string, T>::value ?
     253           76 :                 what::strfunc : what::func)
     254              :     {
     255           76 :     }
     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          287 :     value_ref(
     267              :         T b) noexcept
     268          287 :         : arg_(b)
     269          287 :         , cf_{&from_builtin<bool>, &arg_.bool_}
     270          287 :         , what_(what::cfunc)
     271              :     {
     272          287 :     }
     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         2692 :     value_ref(int t) noexcept
     293         2692 :         : arg_(t)
     294         2692 :         , cf_{&from_builtin<int>, &arg_.int_}
     295         2692 :         , what_(what::cfunc)
     296              :     {
     297         2692 :     }
     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          656 :     value_ref(
     391              :         std::initializer_list<value_ref> init) noexcept
     392          656 :         : arg_(init)
     393          656 :         , what_(what::ini)
     394              :     {
     395          656 :     }
     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.1