|
|
|||
File indexing completed on 2025-12-16 09:54:04
0001 // 0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // Official repository: https://github.com/boostorg/json 0008 // 0009 0010 #ifndef BOOST_JSON_PILFER_HPP 0011 #define BOOST_JSON_PILFER_HPP 0012 0013 #include <boost/json/detail/config.hpp> 0014 #include <type_traits> 0015 #include <utility> 0016 0017 /* 0018 Implements "pilfering" from P0308R0 0019 0020 @see 0021 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html 0022 */ 0023 0024 namespace boost { 0025 namespace json { 0026 0027 /** Tag wrapper to specify pilfer-construction. 0028 0029 This wrapper is used to specify a pilfer constructor 0030 overload. 0031 0032 @par Example 0033 0034 A pilfer constructor accepts a single argument 0035 of type @ref pilfered and throws nothing: 0036 0037 @code 0038 struct T 0039 { 0040 T( pilfered<T> ) noexcept; 0041 }; 0042 @endcode 0043 0044 @note 0045 0046 The constructor should not be marked explicit. 0047 0048 @see @ref pilfer, @ref is_pilfer_constructible, 0049 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html"> 0050 Valueless Variants Considered Harmful</a> 0051 */ 0052 template<class T> 0053 class pilfered 0054 { 0055 T& t_; 0056 0057 public: 0058 /** Constructor 0059 0060 Construct the wrapper from `t`. 0061 0062 @param t The pilferable object. Ownership 0063 is not transferred. 0064 */ 0065 explicit 0066 constexpr 0067 pilfered(T&& t) noexcept 0068 : t_(t) 0069 { 0070 } 0071 0072 /** Return a reference to the pilferable object. 0073 0074 This returns a reference to the wrapped object. 0075 */ 0076 constexpr T& 0077 get() const noexcept 0078 { 0079 return t_; 0080 } 0081 0082 /** Return a pointer to the pilferable object. 0083 0084 This returns a pointer to the wrapped object. 0085 */ 0086 constexpr T* 0087 operator->() const noexcept 0088 { 0089 //return std::addressof(t_); 0090 return reinterpret_cast<T*>( 0091 const_cast<char *>( 0092 &reinterpret_cast< 0093 const volatile char &>(t_))); 0094 } 0095 }; 0096 0097 #ifndef BOOST_JSON_DOCS 0098 // VFALCO Renamed this to work around an msvc bug 0099 namespace detail_pilfer { 0100 template<class> 0101 struct not_pilfered 0102 { 0103 }; 0104 } // detail_pilfer 0105 #endif 0106 0107 /** Metafunction returning `true` if `T` is <em>PilferConstructible</em> 0108 0109 If `T` can be pilfer constructed, this metafunction is 0110 equal to `std::true_type`. Otherwise it is equal to 0111 `std::false_type`. 0112 0113 @see @ref pilfer, @ref pilfered, 0114 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html"> 0115 Valueless Variants Considered Harmful</a> 0116 */ 0117 template<class T> 0118 struct is_pilfer_constructible 0119 #ifndef BOOST_JSON_DOCS 0120 : std::integral_constant<bool, 0121 std::is_nothrow_move_constructible<T>::value || 0122 ( 0123 std::is_nothrow_constructible< 0124 T, pilfered<T> >::value && 0125 ! std::is_nothrow_constructible< 0126 T, detail_pilfer::not_pilfered<T> >::value 0127 )> 0128 #endif 0129 { 0130 }; 0131 0132 /** Indicate that an object `t` may be pilfered from. 0133 0134 A <em>pilfer</em> operation is the construction 0135 of a new object of type `T` from an existing 0136 object `t`. After the construction, the only 0137 valid operation on the pilfered-from object is 0138 destruction. This permits optimizations beyond 0139 those available for a move-construction, as the 0140 pilfered-from object is not required to be in 0141 a "usable" state. 0142 \n 0143 This is used similarly to `std::move`. 0144 0145 @par Example 0146 0147 A pilfer constructor accepts a single argument 0148 of type @ref pilfered and throws nothing: 0149 0150 @code 0151 struct T 0152 { 0153 T( pilfered<T> ) noexcept; 0154 }; 0155 @endcode 0156 0157 Pilfer construction is performed using @ref pilfer : 0158 0159 @code 0160 { 0161 T t1; // default construction 0162 T t2( pilfer( t1 ) ); // pilfer-construct from t1 0163 0164 // At this point, t1 may only be destroyed 0165 } 0166 @endcode 0167 0168 @see @ref pilfered, @ref is_pilfer_constructible, 0169 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html"> 0170 Valueless Variants Considered Harmful</a> 0171 */ 0172 template<class T> 0173 auto 0174 pilfer(T&& t) noexcept -> 0175 typename std::conditional< 0176 std::is_nothrow_constructible< 0177 typename std::remove_reference<T>::type, 0178 pilfered<typename 0179 std::remove_reference<T>::type> >::value && 0180 ! std::is_nothrow_constructible< 0181 typename std::remove_reference<T>::type, 0182 detail_pilfer::not_pilfered<typename 0183 std::remove_reference<T>::type> >::value, 0184 pilfered<typename std::remove_reference<T>::type>, 0185 typename std::remove_reference<T>::type&& 0186 >::type 0187 { 0188 using U = 0189 typename std::remove_reference<T>::type; 0190 static_assert( 0191 is_pilfer_constructible<U>::value, ""); 0192 return typename std::conditional< 0193 std::is_nothrow_constructible< 0194 U, pilfered<U> >::value && 0195 ! std::is_nothrow_constructible< 0196 U, detail_pilfer::not_pilfered<U> >::value, 0197 pilfered<U>, U&& 0198 >::type(std::move(t)); 0199 } 0200 0201 /* 0202 template<class T> 0203 void 0204 relocate(T* dest, T& src) noexcept 0205 { 0206 static_assert( 0207 is_pilfer_constructible<T>::value, ""); 0208 ::new(dest) T(pilfer(src)); 0209 src.~T(); 0210 } 0211 */ 0212 0213 } // json 0214 } // boost 0215 0216 0217 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|