LCOV - code coverage report
Current view: top level - json - pilfer.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 7 7
Test Date: 2026-03-05 09:04:27 Functions: 100.0 % 16 16

           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_PILFER_HPP
      11                 : #define BOOST_JSON_PILFER_HPP
      12                 : 
      13                 : #include <boost/json/detail/config.hpp>
      14                 : #include <type_traits>
      15                 : #include <utility>
      16                 : 
      17                 : /*
      18                 :     Implements "pilfering" from P0308R0
      19                 : 
      20                 :     @see
      21                 :         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html
      22                 : */
      23                 : 
      24                 : namespace boost {
      25                 : namespace json {
      26                 : 
      27                 : /** Tag wrapper to specify pilfer-construction.
      28                 : 
      29                 :     This wrapper is used to specify a pilfer constructor
      30                 :     overload.
      31                 : 
      32                 :     @par Example
      33                 : 
      34                 :     A pilfer constructor accepts a single argument
      35                 :     of type @ref pilfered and throws nothing:
      36                 : 
      37                 :     @code
      38                 :     struct T
      39                 :     {
      40                 :         T( pilfered<T> ) noexcept;
      41                 :     };
      42                 :     @endcode
      43                 : 
      44                 :     @note
      45                 : 
      46                 :     The constructor should not be marked explicit.
      47                 : 
      48                 :     @see @ref pilfer, @ref is_pilfer_constructible,
      49                 :     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
      50                 :         Valueless Variants Considered Harmful</a>
      51                 : */
      52                 : template<class T>
      53                 : class pilfered
      54                 : {
      55                 :     T& t_;
      56                 : 
      57                 : public:
      58                 :     /** Constructor
      59                 : 
      60                 :         Construct the wrapper from `t`.
      61                 : 
      62                 :         @param t The pilferable object. Ownership
      63                 :         is not transferred.
      64                 :     */
      65                 :     explicit
      66                 :     constexpr
      67 HIT     2174037 :     pilfered(T&& t) noexcept
      68         2174037 :         : t_(t)
      69                 :     {
      70         2174037 :     }
      71                 : 
      72                 :     /** Return a reference to the pilferable object.
      73                 : 
      74                 :         This returns a reference to the wrapped object.
      75                 :     */
      76                 :     constexpr T&
      77         4316568 :     get() const noexcept
      78                 :     {
      79         4316568 :         return t_;
      80                 :     }
      81                 : 
      82                 :     /** Return a pointer to the pilferable object.
      83                 : 
      84                 :         This returns a pointer to the wrapped object.
      85                 :     */
      86                 :     constexpr T*
      87                 :     operator->() const noexcept
      88                 :     {
      89                 :         //return std::addressof(t_);
      90                 :         return reinterpret_cast<T*>(
      91                 :             const_cast<char *>(
      92                 :                 &reinterpret_cast<
      93                 :                     const volatile char &>(t_)));
      94                 :     }
      95                 : };
      96                 : 
      97                 : #ifndef BOOST_JSON_DOCS
      98                 : // VFALCO Renamed this to work around an msvc bug
      99                 : namespace detail_pilfer {
     100                 : template<class>
     101                 : struct not_pilfered
     102                 : {
     103                 : };
     104                 : } // detail_pilfer
     105                 : #endif
     106                 : 
     107                 : /** Metafunction returning `true` if `T` is <em>PilferConstructible</em>
     108                 : 
     109                 :     If `T` can be pilfer constructed, this metafunction is
     110                 :     equal to `std::true_type`. Otherwise it is equal to
     111                 :     `std::false_type`.
     112                 : 
     113                 :     @see @ref pilfer, @ref pilfered,
     114                 :     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
     115                 :         Valueless Variants Considered Harmful</a>
     116                 : */
     117                 : template<class T>
     118                 : struct is_pilfer_constructible
     119                 : #ifndef BOOST_JSON_DOCS
     120                 :     : std::integral_constant<bool,
     121                 :         std::is_nothrow_move_constructible<T>::value ||
     122                 :         (
     123                 :             std::is_nothrow_constructible<
     124                 :                 T, pilfered<T> >::value &&
     125                 :             ! std::is_nothrow_constructible<
     126                 :                 T, detail_pilfer::not_pilfered<T> >::value
     127                 :         )>
     128                 : #endif
     129                 : {
     130                 : };
     131                 : 
     132                 : /** Indicate that an object `t` may be pilfered from.
     133                 : 
     134                 :     A <em>pilfer</em> operation is the construction
     135                 :     of a new object of type `T` from an existing
     136                 :     object `t`. After the construction, the only
     137                 :     valid operation on the pilfered-from object is
     138                 :     destruction. This permits optimizations beyond
     139                 :     those available for a move-construction, as the
     140                 :     pilfered-from object is not required to be in
     141                 :     a "usable" state.
     142                 : \n
     143                 :     This is used similarly to `std::move`.
     144                 : 
     145                 :     @par Example
     146                 : 
     147                 :     A pilfer constructor accepts a single argument
     148                 :     of type @ref pilfered and throws nothing:
     149                 : 
     150                 :     @code
     151                 :     struct T
     152                 :     {
     153                 :         T( pilfered<T> ) noexcept;
     154                 :     };
     155                 :     @endcode
     156                 : 
     157                 :     Pilfer construction is performed using @ref pilfer :
     158                 : 
     159                 :     @code
     160                 :     {
     161                 :         T t1;                       // default construction
     162                 :         T t2( pilfer( t1 ) );       // pilfer-construct from t1
     163                 : 
     164                 :         // At this point, t1 may only be destroyed
     165                 :     }
     166                 :     @endcode
     167                 : 
     168                 :     @see @ref pilfered, @ref is_pilfer_constructible,
     169                 :     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
     170                 :         Valueless Variants Considered Harmful</a>
     171                 : */
     172                 : template<class T>
     173                 : auto
     174         6327165 : pilfer(T&& t) noexcept ->
     175                 :     typename std::conditional<
     176                 :         std::is_nothrow_constructible<
     177                 :             typename std::remove_reference<T>::type,
     178                 :             pilfered<typename
     179                 :                 std::remove_reference<T>::type> >::value &&
     180                 :         ! std::is_nothrow_constructible<
     181                 :             typename std::remove_reference<T>::type,
     182                 :             detail_pilfer::not_pilfered<typename
     183                 :                 std::remove_reference<T>::type> >::value,
     184                 :         pilfered<typename std::remove_reference<T>::type>,
     185                 :         typename std::remove_reference<T>::type&&
     186                 :             >::type
     187                 : {
     188                 :     using U =
     189                 :         typename std::remove_reference<T>::type;
     190                 :     static_assert(
     191                 :         is_pilfer_constructible<U>::value, "");
     192                 :     return typename std::conditional<
     193                 :         std::is_nothrow_constructible<
     194                 :             U, pilfered<U> >::value &&
     195                 :         ! std::is_nothrow_constructible<
     196                 :             U, detail_pilfer::not_pilfered<U> >::value,
     197                 :         pilfered<U>, U&&
     198         6327165 :             >::type(std::move(t));
     199                 : }
     200                 : 
     201                 : /*
     202                 : template<class T>
     203                 : void
     204                 : relocate(T* dest, T& src) noexcept
     205                 : {
     206                 :     static_assert(
     207                 :         is_pilfer_constructible<T>::value, "");
     208                 :     ::new(dest) T(pilfer(src));
     209                 :     src.~T();
     210                 : }
     211                 : */
     212                 : 
     213                 : } // json
     214                 : } // boost
     215                 : 
     216                 : 
     217                 : #endif
        

Generated by: LCOV version 2.3