LCOV - code coverage report
Current view: top level - json - pilfer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 7 7
Test Date: 2026-01-05 13:48:39 Functions: 100.0 % 16 16

            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      2174071 :     pilfered(T&& t) noexcept
      69      2174071 :         : t_(t)
      70              :     {
      71      2174071 :     }
      72              : 
      73              :     /** Return a reference to the pilferable object.
      74              : 
      75              :         This returns a reference to the wrapped object.
      76              :     */
      77              :     constexpr T&
      78      4316710 :     get() const noexcept
      79              :     {
      80      4316710 :         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      6327199 : 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      6327199 :             >::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.1