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: 2025-12-23 17:20:51 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/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      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.1