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:20:51 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
      35              :     lazy construction of and assignment to the
      36              :     container types @ref value, @ref array,
      37              :     and @ref object. The two types of initializer
      38              :     lists used are:
      39              : 
      40              :     @li `std::initializer_list< value_ref >` for
      41              :     constructing or assigning a @ref value or
      42              :     @ref array, and
      43              : 
      44              :     @li `std::initializer_list< std::pair< string_view, value_ref > >`
      45              :     for constructing or assigning an @ref object.
      46              : 
      47              :     A `value_ref` uses reference semantics. Creation of the actual container
      48              :     from the initializer list is lazily deferred until the list is used. This
      49              :     means that the `boost::container::pmr::memory_resource` used to construct a
      50              :     container can be specified after the point where the initializer list is
      51              :     specified.
      52              : 
      53              :     @par Example
      54              : 
      55              :     This example demonstrates how a user-defined type
      56              :     containing a JSON value can be constructed from
      57              :     an initializer list:
      58              : 
      59              :     @code
      60              : 
      61              :     class my_type
      62              :     {
      63              :         value jv_;
      64              : 
      65              :     public:
      66              :         my_type( std::initializer_list< value_ref > init )
      67              :             : jv_(init)
      68              :         {
      69              :         }
      70              :     };
      71              : 
      72              :     @endcode
      73              : 
      74              :     @note Never declare a variable of type
      75              :     `std::initializer_list` except in function
      76              :     parameter lists, otherwise the behavior may
      77              :     be undefined.
      78              : 
      79              :     @see
      80              :         @ref value,
      81              :         @ref array,
      82              :         @ref object
      83              : */
      84              : class value_ref
      85              : {
      86              :     friend class value;
      87              :     friend class object;
      88              :     friend class array;
      89              : 
      90              :     friend class value_ref_test;
      91              : 
      92              :     enum class what
      93              :     {
      94              :         str,
      95              :         ini,
      96              :         func,
      97              :         cfunc,
      98              :         strfunc,
      99              :     };
     100              : 
     101              :     using init_list =
     102              :         std::initializer_list<value_ref>;
     103              : 
     104              :     struct func_type
     105              :     {
     106              :         value(*f)(void*, storage_ptr);
     107              :         void* p;
     108              :     };
     109              : 
     110              :     struct cfunc_type
     111              :     {
     112              :         value(*f)(void const*, storage_ptr);
     113              :         void const* p;
     114              :     };
     115              : 
     116              :     union arg_type
     117              :     {
     118              :         string_view         str_;
     119              :         init_list           init_list_;
     120              : 
     121              :         signed char         schar_;
     122              :         short               short_;
     123              :         int                 int_;
     124              :         long                long_;
     125              :         long long           long_long_;
     126              :         unsigned char       uchar_;
     127              :         unsigned short      ushort_;
     128              :         unsigned int        uint_;
     129              :         unsigned long       ulong_;
     130              :         unsigned long long  ulong_long_;
     131              :         float               float_;
     132              :         double              double_;
     133              :         bool                bool_;
     134              :         std::nullptr_t      nullptr_;
     135              : 
     136           98 :         arg_type() {}
     137         1002 :         explicit arg_type(string_view t) noexcept : str_(t) {}
     138          674 :         explicit arg_type(init_list t) noexcept : init_list_(t) {}
     139            1 :         explicit arg_type(signed char t) noexcept : schar_(t) {}
     140            3 :         explicit arg_type(short t) noexcept : short_(t) {}
     141         2728 :         explicit arg_type(int t) noexcept : int_(t) {}
     142            3 :         explicit arg_type(long t) noexcept : long_(t) {}
     143            3 :         explicit arg_type(long long t) noexcept : long_long_(t) {}
     144           21 :         explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
     145            3 :         explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
     146           45 :         explicit arg_type(unsigned int t) noexcept : uint_(t) {}
     147            3 :         explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
     148            3 :         explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
     149           18 :         explicit arg_type(float t) noexcept : float_(t) {}
     150           34 :         explicit arg_type(double t) noexcept : double_(t) {}
     151          287 :         explicit arg_type(bool t) noexcept : bool_(t) {}
     152           88 :         explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
     153              :     };
     154              : 
     155              :     arg_type arg_;
     156              : #ifndef BOOST_JSON_DOCS
     157              :     // VFALCO doc toolchain erroneously
     158              :     // displays private, anonymous unions as public
     159              :     union
     160              :     {
     161              :         func_type f_;
     162              :         cfunc_type cf_;
     163              :     };
     164              : #endif
     165              :     what what_;
     166              : 
     167              : public:
     168              :     /// Constructor
     169              :     value_ref(
     170              :         value_ref const&) = default;
     171              : 
     172              :     /// Constructor
     173              :     value_ref(
     174              :         value_ref&&) = default;
     175              : 
     176              :     /// Constructor
     177              : #ifdef BOOST_JSON_DOCS
     178              :     value_ref(string_view s) noexcept;
     179              : #else
     180              :     template<
     181              :         class T
     182              :         ,class = typename
     183              :             std::enable_if<
     184              :                 std::is_constructible<
     185              :                     string_view, T>::value>::type
     186              :     >
     187         1002 :     value_ref(
     188              :         T const& t) noexcept
     189         1002 :         : arg_(string_view(t))
     190         1002 :         , what_(what::str)
     191              :     {
     192              : 
     193         1002 :     }
     194              : #endif
     195              : 
     196              :     /// Constructor
     197              :     template<class T>
     198           22 :     value_ref(
     199              :         T const& t
     200              : #ifndef BOOST_JSON_DOCS
     201              :         ,typename std::enable_if<
     202              :             ! std::is_constructible<
     203              :                 string_view, T>::value &&
     204              :             ! std::is_same<bool, T>::value
     205              :                 >::type* = 0
     206              : #endif
     207              :         ) noexcept
     208           22 :         : cf_{&from_const<T>, &t}
     209           22 :         , what_(what::cfunc)
     210              :     {
     211           22 :     }
     212              : 
     213              :     /// Constructor
     214              :     template<class T>
     215           76 :     value_ref(
     216              :         T&& t
     217              : #ifndef BOOST_JSON_DOCS
     218              :         ,typename std::enable_if<
     219              :             (! std::is_constructible<
     220              :                 string_view, T>::value ||
     221              :             std::is_same<string, T>::value) &&
     222              :             ! std::is_same<bool,
     223              :                 detail::remove_cvref<T>>::value &&
     224              :             std::is_same<T, detail::remove_cvref<T>>
     225              :                 ::value>::type* = 0
     226              : #endif
     227              :         ) noexcept
     228           76 :         : f_{&from_rvalue<
     229              :             detail::remove_cvref<T>>, &t}
     230           76 :         , what_(std::is_same<string, T>::value ?
     231           76 :                 what::strfunc : what::func)
     232              :     {
     233           76 :     }
     234              : 
     235              :     /// Constructor
     236              : #ifdef BOOST_JSON_DOCS
     237              :     value_ref(bool b) noexcept;
     238              : #else
     239              :     template<
     240              :         class T
     241              :         ,class = typename std::enable_if<
     242              :             std::is_same<T, bool>::value>::type
     243              :     >
     244          287 :     value_ref(
     245              :         T b) noexcept
     246          287 :         : arg_(b)
     247          287 :         , cf_{&from_builtin<bool>, &arg_.bool_}
     248          287 :         , what_(what::cfunc)
     249              :     {
     250          287 :     }
     251              : #endif
     252              : 
     253              :     /// Constructor
     254          674 :     value_ref(
     255              :         std::initializer_list<
     256              :             value_ref> t) noexcept
     257          674 :         : arg_(t)
     258          674 :         , what_(what::ini)
     259              :     {
     260          674 :     }
     261              : 
     262              :     /// Constructor
     263            1 :     value_ref(signed char t) noexcept
     264            1 :         : arg_(t)
     265            1 :         , cf_{&from_builtin<signed char>, &arg_.schar_}
     266            1 :         , what_(what::cfunc)
     267              :     {
     268            1 :     }
     269              : 
     270              :     /// Constructor
     271            3 :     value_ref(short t) noexcept
     272            3 :         : arg_(t)
     273            3 :         , cf_{&from_builtin<short>, &arg_.short_}
     274            3 :         , what_(what::cfunc)
     275              :     {
     276            3 :     }
     277              : 
     278              :     /// Constructor
     279         2728 :     value_ref(int t) noexcept
     280         2728 :         : arg_(t)
     281         2728 :         , cf_{&from_builtin<int>, &arg_.int_}
     282         2728 :         , what_(what::cfunc)
     283              :     {
     284         2728 :     }
     285              : 
     286              :     /// Constructor
     287            3 :     value_ref(long t) noexcept
     288            3 :         : arg_(t)
     289            3 :         , cf_{&from_builtin<
     290            3 :             long>, &arg_.long_}
     291            3 :         , what_(what::cfunc)
     292              :     {
     293            3 :     }
     294              : 
     295              :     /// Constructor
     296            3 :     value_ref(long long t) noexcept
     297            3 :         : arg_(t)
     298            3 :         , cf_{&from_builtin<
     299            3 :             long long>, &arg_.long_long_}
     300            3 :         , what_(what::cfunc)
     301              :     {
     302            3 :     }
     303              : 
     304              :     /// Constructor
     305           21 :     value_ref(unsigned char t) noexcept
     306           21 :         : arg_(t)
     307           21 :         , cf_{&from_builtin<
     308           21 :             unsigned char>, &arg_.uchar_}
     309           21 :         , what_(what::cfunc)
     310              :     {
     311           21 :     }
     312              : 
     313              :     /// Constructor
     314            3 :     value_ref(unsigned short t) noexcept
     315            3 :         : arg_(t)
     316            3 :         , cf_{&from_builtin<
     317            3 :             unsigned short>, &arg_.ushort_}
     318            3 :         , what_(what::cfunc)
     319              :     {
     320            3 :     }
     321              : 
     322              :     /// Constructor
     323           45 :     value_ref(unsigned int t) noexcept
     324           45 :         : arg_(t)
     325           45 :         , cf_{&from_builtin<
     326           45 :             unsigned int>, &arg_.uint_}
     327           45 :         , what_(what::cfunc)
     328              :     {
     329           45 :     }
     330              : 
     331              :     /// Constructor
     332            3 :     value_ref(unsigned long t) noexcept
     333            3 :         : arg_(t)
     334            3 :         , cf_{&from_builtin<
     335            3 :             unsigned long>, &arg_.ulong_}
     336            3 :         , what_(what::cfunc)
     337              :     {
     338            3 :     }
     339              : 
     340              :     /// Constructor
     341            3 :     value_ref(unsigned long long t) noexcept
     342            3 :         : arg_(t)
     343            3 :         , cf_{&from_builtin<
     344            3 :             unsigned long long>, &arg_.ulong_long_}
     345            3 :         , what_(what::cfunc)
     346              :     {
     347            3 :     }
     348              : 
     349              :     /// Constructor
     350           18 :     value_ref(float t) noexcept
     351           18 :         : arg_(t)
     352           18 :         , cf_{&from_builtin<
     353           18 :             float>, &arg_.float_}
     354           18 :         , what_(what::cfunc)
     355              :     {
     356           18 :     }
     357              : 
     358              :     /// Constructor
     359           34 :     value_ref(double t) noexcept
     360           34 :         : arg_(t)
     361           34 :         , cf_{&from_builtin<
     362           34 :             double>, &arg_.double_}
     363           34 :         , what_(what::cfunc)
     364              :     {
     365           34 :     }
     366              : 
     367              :     /// Constructor
     368           88 :     value_ref(std::nullptr_t) noexcept
     369           88 :         : arg_(nullptr)
     370           88 :         , cf_{&from_builtin<
     371           88 :             std::nullptr_t>, &arg_.nullptr_}
     372           88 :         , what_(what::cfunc)
     373              :     {
     374           88 :     }
     375              : 
     376              : #ifndef BOOST_JSON_DOCS
     377              : // Not public
     378              : //private:
     379              :     // VFALCO Why is this needed?
     380              :     /** Operator conversion to @ref value
     381              : 
     382              :         This allows creation of a @ref value from
     383              :         an initializer list element.
     384              :     */
     385              :     BOOST_JSON_DECL
     386              :     operator value() const;
     387              : #endif
     388              : 
     389              : private:
     390              :     template<class T>
     391              :     static
     392              :     value
     393              :     from_builtin(
     394              :         void const* p,
     395              :         storage_ptr sp) noexcept;
     396              : 
     397              :     template<class T>
     398              :     static
     399              :     value
     400              :     from_const(
     401              :         void const* p,
     402              :         storage_ptr sp);
     403              : 
     404              :     template<class T>
     405              :     static
     406              :     value
     407              :     from_rvalue(
     408              :         void* p,
     409              :         storage_ptr sp);
     410              : 
     411              :     static
     412              :     BOOST_JSON_DECL
     413              :     value
     414              :     from_init_list(
     415              :         void const* p,
     416              :         storage_ptr sp);
     417              : 
     418              :     inline
     419              :     bool
     420              :     is_key_value_pair() const noexcept;
     421              : 
     422              :     static
     423              :     inline
     424              :     bool
     425              :     maybe_object(
     426              :         std::initializer_list<
     427              :             value_ref> init) noexcept;
     428              : 
     429              :     inline
     430              :     string_view
     431              :     get_string() const noexcept;
     432              : 
     433              :     BOOST_JSON_DECL
     434              :     value
     435              :     make_value(
     436              :         storage_ptr sp) const;
     437              : 
     438              :     BOOST_JSON_DECL
     439              :     static
     440              :     value
     441              :     make_value(
     442              :         std::initializer_list<
     443              :             value_ref> init,
     444              :         storage_ptr sp);
     445              : 
     446              :     BOOST_JSON_DECL
     447              :     static
     448              :     object
     449              :     make_object(
     450              :         std::initializer_list<value_ref> init,
     451              :         storage_ptr sp);
     452              : 
     453              :     BOOST_JSON_DECL
     454              :     static
     455              :     array
     456              :     make_array(
     457              :         std::initializer_list<
     458              :             value_ref> init,
     459              :         storage_ptr sp);
     460              : 
     461              :     BOOST_JSON_DECL
     462              :     static
     463              :     void
     464              :     write_array(
     465              :         value* dest,
     466              :         std::initializer_list<
     467              :             value_ref> init,
     468              :         storage_ptr const& sp);
     469              : };
     470              : 
     471              : } // namespace json
     472              : } // namespace boost
     473              : 
     474              : // Must be included here for this file to stand alone
     475              : #include <boost/json/value.hpp>
     476              : 
     477              : // includes are at the bottom of <boost/json/value.hpp>
     478              : //#include <boost/json/impl/value.hpp>
     479              : //#include <boost/json/impl/value.ipp>
     480              : 
     481              : #endif
        

Generated by: LCOV version 2.1