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-03-05 09:04:27 Functions: 96.4 % 56 54 2

           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
      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 HIT          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.3