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:21:58 Functions: 96.5 % 57 55

            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          125 :         arg_type() {}
     137          911 :         explicit arg_type(string_view t) noexcept : str_(t) {}
     138          655 :         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         2684 :         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              : #ifdef BOOST_JSON_DOCS
     174              :     value_ref(string_view s) noexcept;
     175              : #else
     176              :     template<
     177              :         class T
     178              :         ,class = typename
     179              :             std::enable_if<
     180              :                 std::is_constructible<
     181              :                     string_view, T>::value>::type
     182              :     >
     183          911 :     value_ref(
     184              :         T const& t) noexcept
     185          911 :         : arg_(string_view(t))
     186          911 :         , what_(what::str)
     187              :     {
     188              : 
     189          911 :     }
     190              : #endif
     191              : 
     192              :     /// Constructor
     193              :     template<class T>
     194           22 :     value_ref(
     195              :         T const& t
     196              : #ifndef BOOST_JSON_DOCS
     197              :         ,typename std::enable_if<
     198              :             ! std::is_constructible<
     199              :                 string_view, T>::value &&
     200              :             ! std::is_same<bool, T>::value
     201              :                 >::type* = 0
     202              : #endif
     203              :         ) noexcept
     204           22 :         : cf_{&from_const<T>, &t}
     205           22 :         , what_(what::cfunc)
     206              :     {
     207           22 :     }
     208              : 
     209              :     /// Constructor
     210              :     template<class T>
     211          103 :     value_ref(
     212              :         T&& t
     213              : #ifndef BOOST_JSON_DOCS
     214              :         ,typename std::enable_if<
     215              :             (! std::is_constructible<
     216              :                 string_view, T>::value ||
     217              :             std::is_same<string, T>::value) &&
     218              :             ! std::is_same<bool,
     219              :                 detail::remove_cvref<T>>::value &&
     220              :             std::is_same<T, detail::remove_cvref<T>>
     221              :                 ::value>::type* = 0
     222              : #endif
     223              :         ) noexcept
     224          103 :         : f_{&from_rvalue<
     225              :             detail::remove_cvref<T>>, &t}
     226          103 :         , what_(std::is_same<string, T>::value ?
     227          103 :                 what::strfunc : what::func)
     228              :     {
     229          103 :     }
     230              : 
     231              :     /// Constructor
     232              : #ifdef BOOST_JSON_DOCS
     233              :     value_ref(bool b) noexcept;
     234              : #else
     235              :     template<
     236              :         class T
     237              :         ,class = typename std::enable_if<
     238              :             std::is_same<T, bool>::value>::type
     239              :     >
     240          287 :     value_ref(
     241              :         T b) noexcept
     242          287 :         : arg_(b)
     243          287 :         , cf_{&from_builtin<bool>, &arg_.bool_}
     244          287 :         , what_(what::cfunc)
     245              :     {
     246          287 :     }
     247              : #endif
     248              : 
     249              :     /// Constructor
     250          655 :     value_ref(
     251              :         std::initializer_list<
     252              :             value_ref> t) noexcept
     253          655 :         : arg_(t)
     254          655 :         , what_(what::ini)
     255              :     {
     256          655 :     }
     257              : 
     258              :     /// Constructor
     259            1 :     value_ref(signed char t) noexcept
     260            1 :         : arg_(t)
     261            1 :         , cf_{&from_builtin<signed char>, &arg_.schar_}
     262            1 :         , what_(what::cfunc)
     263              :     {
     264            1 :     }
     265              : 
     266              :     /// Constructor
     267            3 :     value_ref(short t) noexcept
     268            3 :         : arg_(t)
     269            3 :         , cf_{&from_builtin<short>, &arg_.short_}
     270            3 :         , what_(what::cfunc)
     271              :     {
     272            3 :     }
     273              : 
     274              :     /// Constructor
     275         2684 :     value_ref(int t) noexcept
     276         2684 :         : arg_(t)
     277         2684 :         , cf_{&from_builtin<int>, &arg_.int_}
     278         2684 :         , what_(what::cfunc)
     279              :     {
     280         2684 :     }
     281              : 
     282              :     /// Constructor
     283            3 :     value_ref(long t) noexcept
     284            3 :         : arg_(t)
     285            3 :         , cf_{&from_builtin<
     286            3 :             long>, &arg_.long_}
     287            3 :         , what_(what::cfunc)
     288              :     {
     289            3 :     }
     290              : 
     291              :     /// Constructor
     292            3 :     value_ref(long long t) noexcept
     293            3 :         : arg_(t)
     294            3 :         , cf_{&from_builtin<
     295            3 :             long long>, &arg_.long_long_}
     296            3 :         , what_(what::cfunc)
     297              :     {
     298            3 :     }
     299              : 
     300              :     /// Constructor
     301           21 :     value_ref(unsigned char t) noexcept
     302           21 :         : arg_(t)
     303           21 :         , cf_{&from_builtin<
     304           21 :             unsigned char>, &arg_.uchar_}
     305           21 :         , what_(what::cfunc)
     306              :     {
     307           21 :     }
     308              : 
     309              :     /// Constructor
     310            3 :     value_ref(unsigned short t) noexcept
     311            3 :         : arg_(t)
     312            3 :         , cf_{&from_builtin<
     313            3 :             unsigned short>, &arg_.ushort_}
     314            3 :         , what_(what::cfunc)
     315              :     {
     316            3 :     }
     317              : 
     318              :     /// Constructor
     319           45 :     value_ref(unsigned int t) noexcept
     320           45 :         : arg_(t)
     321           45 :         , cf_{&from_builtin<
     322           45 :             unsigned int>, &arg_.uint_}
     323           45 :         , what_(what::cfunc)
     324              :     {
     325           45 :     }
     326              : 
     327              :     /// Constructor
     328            3 :     value_ref(unsigned long t) noexcept
     329            3 :         : arg_(t)
     330            3 :         , cf_{&from_builtin<
     331            3 :             unsigned long>, &arg_.ulong_}
     332            3 :         , what_(what::cfunc)
     333              :     {
     334            3 :     }
     335              : 
     336              :     /// Constructor
     337            3 :     value_ref(unsigned long long t) noexcept
     338            3 :         : arg_(t)
     339            3 :         , cf_{&from_builtin<
     340            3 :             unsigned long long>, &arg_.ulong_long_}
     341            3 :         , what_(what::cfunc)
     342              :     {
     343            3 :     }
     344              : 
     345              :     /// Constructor
     346           18 :     value_ref(float t) noexcept
     347           18 :         : arg_(t)
     348           18 :         , cf_{&from_builtin<
     349           18 :             float>, &arg_.float_}
     350           18 :         , what_(what::cfunc)
     351              :     {
     352           18 :     }
     353              : 
     354              :     /// Constructor
     355           34 :     value_ref(double t) noexcept
     356           34 :         : arg_(t)
     357           34 :         , cf_{&from_builtin<
     358           34 :             double>, &arg_.double_}
     359           34 :         , what_(what::cfunc)
     360              :     {
     361           34 :     }
     362              : 
     363              :     /// Constructor
     364           88 :     value_ref(std::nullptr_t) noexcept
     365           88 :         : arg_(nullptr)
     366           88 :         , cf_{&from_builtin<
     367           88 :             std::nullptr_t>, &arg_.nullptr_}
     368           88 :         , what_(what::cfunc)
     369              :     {
     370           88 :     }
     371              : 
     372              : #ifndef BOOST_JSON_DOCS
     373              : // Not public
     374              : //private:
     375              :     // VFALCO Why is this needed?
     376              :     /** Operator conversion to @ref value
     377              : 
     378              :         This allows creation of a @ref value from
     379              :         an initializer list element.
     380              :     */
     381              :     BOOST_JSON_DECL
     382              :     operator value() const;
     383              : #endif
     384              : 
     385              : private:
     386              :     template<class T>
     387              :     static
     388              :     value
     389              :     from_builtin(
     390              :         void const* p,
     391              :         storage_ptr sp) noexcept;
     392              : 
     393              :     template<class T>
     394              :     static
     395              :     value
     396              :     from_const(
     397              :         void const* p,
     398              :         storage_ptr sp);
     399              : 
     400              :     template<class T>
     401              :     static
     402              :     value
     403              :     from_rvalue(
     404              :         void* p,
     405              :         storage_ptr sp);
     406              : 
     407              :     static
     408              :     BOOST_JSON_DECL
     409              :     value
     410              :     from_init_list(
     411              :         void const* p,
     412              :         storage_ptr sp);
     413              : 
     414              :     inline
     415              :     bool
     416              :     is_key_value_pair() const noexcept;
     417              : 
     418              :     static
     419              :     inline
     420              :     bool
     421              :     maybe_object(
     422              :         std::initializer_list<
     423              :             value_ref> init) noexcept;
     424              : 
     425              :     inline
     426              :     string_view
     427              :     get_string() const noexcept;
     428              : 
     429              :     BOOST_JSON_DECL
     430              :     value
     431              :     make_value(
     432              :         storage_ptr sp) const;
     433              : 
     434              :     BOOST_JSON_DECL
     435              :     static
     436              :     value
     437              :     make_value(
     438              :         std::initializer_list<
     439              :             value_ref> init,
     440              :         storage_ptr sp);
     441              : 
     442              :     BOOST_JSON_DECL
     443              :     static
     444              :     object
     445              :     make_object(
     446              :         std::initializer_list<value_ref> init,
     447              :         storage_ptr sp);
     448              : 
     449              :     BOOST_JSON_DECL
     450              :     static
     451              :     array
     452              :     make_array(
     453              :         std::initializer_list<
     454              :             value_ref> init,
     455              :         storage_ptr sp);
     456              : 
     457              :     BOOST_JSON_DECL
     458              :     static
     459              :     void
     460              :     write_array(
     461              :         value* dest,
     462              :         std::initializer_list<
     463              :             value_ref> init,
     464              :         storage_ptr const& sp);
     465              : };
     466              : 
     467              : } // namespace json
     468              : } // namespace boost
     469              : 
     470              : // Must be included here for this file to stand alone
     471              : #include <boost/json/value.hpp>
     472              : 
     473              : // includes are at the bottom of <boost/json/value.hpp>
     474              : //#include <boost/json/impl/value.hpp>
     475              : //#include <boost/json/impl/value.ipp>
     476              : 
     477              : #endif
        

Generated by: LCOV version 2.1