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

Generated by: LCOV version 2.3