Line data Source code
1 : // Distributed under the Boost Software License, Version 1.0. (See 2 : // accompanying file LICENSE_1_0.txt or copy at 3 : // http://www.boost.org/LICENSE_1_0.txt) 4 : // (C) Copyright 2007-8 Anthony Williams 5 : // (C) Copyright 2011-2012 Vicente J. Botet Escriba 6 : 7 : #ifndef BOOST_THREAD_MOVE_HPP 8 : #define BOOST_THREAD_MOVE_HPP 9 : 10 : #include <boost/thread/detail/config.hpp> 11 : #ifndef BOOST_NO_SFINAE 12 : #include <boost/core/enable_if.hpp> 13 : #include <boost/type_traits/is_convertible.hpp> 14 : #include <boost/type_traits/remove_reference.hpp> 15 : #include <boost/type_traits/remove_cv.hpp> 16 : #include <boost/type_traits/decay.hpp> 17 : #include <boost/type_traits/conditional.hpp> 18 : #include <boost/type_traits/remove_extent.hpp> 19 : #include <boost/type_traits/is_array.hpp> 20 : #include <boost/type_traits/is_function.hpp> 21 : #include <boost/type_traits/add_pointer.hpp> 22 : #endif 23 : 24 : #include <boost/thread/detail/delete.hpp> 25 : #include <boost/move/utility.hpp> 26 : #include <boost/move/traits.hpp> 27 : #include <boost/config/abi_prefix.hpp> 28 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 29 : #include <type_traits> 30 : #endif 31 : namespace boost 32 : { 33 : 34 : namespace detail 35 : { 36 : template <typename T> 37 : struct enable_move_utility_emulation_dummy_specialization; 38 : template<typename T> 39 : struct thread_move_t 40 : { 41 : T& t; 42 : explicit thread_move_t(T& t_): 43 : t(t_) 44 : {} 45 : 46 : T& operator*() const 47 : { 48 : return t; 49 : } 50 : 51 : T* operator->() const 52 : { 53 : return &t; 54 : } 55 : private: 56 : void operator=(thread_move_t&); 57 : }; 58 : } 59 : 60 : #if !defined BOOST_THREAD_USES_MOVE 61 : 62 : #ifndef BOOST_NO_SFINAE 63 : template<typename T> 64 : typename enable_if<boost::is_convertible<T&,boost::detail::thread_move_t<T> >, boost::detail::thread_move_t<T> >::type move(T& t) 65 : { 66 : return boost::detail::thread_move_t<T>(t); 67 : } 68 : #endif 69 : 70 : template<typename T> 71 : boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t) 72 : { 73 : return t; 74 : } 75 : 76 : #endif //#if !defined BOOST_THREAD_USES_MOVE 77 : } 78 : 79 : #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 80 : 81 : #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE) 82 : #define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) 83 : #define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE) 84 : #define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG 85 : #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END 86 : #define BOOST_THREAD_RV(V) V 87 : #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE 88 : #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) 89 : #define BOOST_THREAD_DCL_MOVABLE(TYPE) 90 : #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ 91 : namespace detail { \ 92 : template <typename T> \ 93 : struct enable_move_utility_emulation_dummy_specialization< 94 : 95 : #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ 96 : namespace detail { \ 97 : template <typename T1, typename T2> \ 98 : struct enable_move_utility_emulation_dummy_specialization< 99 : 100 : #define BOOST_THREAD_DCL_MOVABLE_END > \ 101 : : integral_constant<bool, false> \ 102 : {}; \ 103 : } 104 : 105 : #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_MSVC 106 : 107 : #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE) 108 : #define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) 109 : #define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE) 110 : #define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG 111 : #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END 112 : #define BOOST_THREAD_RV(V) V 113 : #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE 114 : #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) 115 : #define BOOST_THREAD_DCL_MOVABLE(TYPE) 116 : #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ 117 : namespace detail { \ 118 : template <typename T> \ 119 : struct enable_move_utility_emulation_dummy_specialization< 120 : 121 : #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ 122 : namespace detail { \ 123 : template <typename T1, typename T2> \ 124 : struct enable_move_utility_emulation_dummy_specialization< 125 : 126 : #define BOOST_THREAD_DCL_MOVABLE_END > \ 127 : : integral_constant<bool, false> \ 128 : {}; \ 129 : } 130 : 131 : #else 132 : 133 : #if defined BOOST_THREAD_USES_MOVE 134 : #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE) 135 : #define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) 136 : #define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE) 137 : #define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG 138 : #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END 139 : #define BOOST_THREAD_RV(V) V 140 : #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) 141 : #define BOOST_THREAD_DCL_MOVABLE(TYPE) 142 : #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ 143 : namespace detail { \ 144 : template <typename T> \ 145 : struct enable_move_utility_emulation_dummy_specialization< 146 : 147 : #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ 148 : namespace detail { \ 149 : template <typename T1, typename T2> \ 150 : struct enable_move_utility_emulation_dummy_specialization< 151 : 152 : #define BOOST_THREAD_DCL_MOVABLE_END > \ 153 : : integral_constant<bool, false> \ 154 : {}; \ 155 : } 156 : 157 : #else 158 : 159 : #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) const TYPE& 160 : #define BOOST_THREAD_RV_REF(TYPE) boost::detail::thread_move_t< TYPE > 161 : #define BOOST_THREAD_RV_REF_BEG boost::detail::thread_move_t< 162 : #define BOOST_THREAD_RV_REF_END > 163 : #define BOOST_THREAD_RV(V) (*V) 164 : #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) 165 : 166 : #define BOOST_THREAD_DCL_MOVABLE(TYPE) \ 167 : template <> \ 168 : struct enable_move_utility_emulation< TYPE > \ 169 : { \ 170 : static const bool value = false; \ 171 : }; 172 : 173 : #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ 174 : template <typename T> \ 175 : struct enable_move_utility_emulation< 176 : 177 : #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ 178 : template <typename T1, typename T2> \ 179 : struct enable_move_utility_emulation< 180 : 181 : #define BOOST_THREAD_DCL_MOVABLE_END > \ 182 : { \ 183 : static const bool value = false; \ 184 : }; 185 : 186 : #endif 187 : 188 : namespace boost 189 : { 190 : namespace detail 191 : { 192 : template <typename T> 193 : BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) 194 : make_rv_ref(T v) BOOST_NOEXCEPT 195 : { 196 : return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); 197 : } 198 : // template <typename T> 199 : // BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) 200 : // make_rv_ref(T &v) BOOST_NOEXCEPT 201 : // { 202 : // return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); 203 : // } 204 : // template <typename T> 205 : // const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) 206 : // make_rv_ref(T const&v) BOOST_NOEXCEPT 207 : // { 208 : // return (const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); 209 : // } 210 : } 211 : } 212 : 213 : #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE.move() 214 : //#define BOOST_THREAD_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE) 215 : #endif 216 : 217 : 218 : #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 219 : 220 : #define BOOST_THREAD_MOVABLE(TYPE) 221 : 222 : #define BOOST_THREAD_COPYABLE(TYPE) 223 : 224 : #else 225 : 226 : #if defined BOOST_THREAD_USES_MOVE 227 : 228 : #define BOOST_THREAD_MOVABLE(TYPE) \ 229 : ::boost::rv<TYPE>& move() BOOST_NOEXCEPT \ 230 : { \ 231 : return *static_cast< ::boost::rv<TYPE>* >(this); \ 232 : } \ 233 : const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \ 234 : { \ 235 : return *static_cast<const ::boost::rv<TYPE>* >(this); \ 236 : } \ 237 : operator ::boost::rv<TYPE>&() \ 238 : { \ 239 : return *static_cast< ::boost::rv<TYPE>* >(this); \ 240 : } \ 241 : operator const ::boost::rv<TYPE>&() const \ 242 : { \ 243 : return *static_cast<const ::boost::rv<TYPE>* >(this); \ 244 : }\ 245 : 246 : #define BOOST_THREAD_COPYABLE(TYPE) \ 247 : TYPE& operator=(TYPE &t)\ 248 : { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;} 249 : 250 : 251 : #else 252 : 253 : #define BOOST_THREAD_MOVABLE(TYPE) \ 254 : operator ::boost::detail::thread_move_t<TYPE>() BOOST_NOEXCEPT \ 255 : { \ 256 : return move(); \ 257 : } \ 258 : ::boost::detail::thread_move_t<TYPE> move() BOOST_NOEXCEPT \ 259 : { \ 260 : ::boost::detail::thread_move_t<TYPE> x(*this); \ 261 : return x; \ 262 : } \ 263 : 264 : #define BOOST_THREAD_COPYABLE(TYPE) 265 : 266 : #endif 267 : #endif 268 : 269 : #define BOOST_THREAD_MOVABLE_ONLY(TYPE) \ 270 : BOOST_THREAD_NO_COPYABLE(TYPE) \ 271 : BOOST_THREAD_MOVABLE(TYPE) \ 272 : typedef int boost_move_no_copy_constructor_or_assign; \ 273 : 274 : 275 : #define BOOST_THREAD_COPYABLE_AND_MOVABLE(TYPE) \ 276 : BOOST_THREAD_COPYABLE(TYPE) \ 277 : BOOST_THREAD_MOVABLE(TYPE) \ 278 : 279 : 280 : 281 : namespace boost 282 : { 283 : namespace thread_detail 284 : { 285 : 286 : #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 287 : #elif defined BOOST_THREAD_USES_MOVE 288 : template <class T> 289 : struct is_rv 290 : : ::boost::move_detail::is_rv<T> 291 : {}; 292 : 293 : #else 294 : template <class T> 295 : struct is_rv 296 : : ::boost::integral_constant<bool, false> 297 : {}; 298 : 299 : template <class T> 300 : struct is_rv< ::boost::detail::thread_move_t<T> > 301 : : ::boost::integral_constant<bool, true> 302 : {}; 303 : 304 : template <class T> 305 : struct is_rv< const ::boost::detail::thread_move_t<T> > 306 : : ::boost::integral_constant<bool, true> 307 : {}; 308 : #endif 309 : 310 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 311 : template <class Tp> 312 : struct remove_reference : boost::remove_reference<Tp> {}; 313 : template <class Tp> 314 : struct decay : boost::decay<Tp> {}; 315 : #else 316 : template <class Tp> 317 : struct remove_reference 318 : { 319 : typedef Tp type; 320 : }; 321 : template <class Tp> 322 : struct remove_reference<Tp&> 323 : { 324 : typedef Tp type; 325 : }; 326 : template <class Tp> 327 : struct remove_reference< rv<Tp> > { 328 : typedef Tp type; 329 : }; 330 : 331 : template <class Tp> 332 : struct decay 333 : { 334 : private: 335 : typedef typename boost::move_detail::remove_rvalue_reference<Tp>::type Up0; 336 : typedef typename boost::remove_reference<Up0>::type Up; 337 : public: 338 : typedef typename conditional 339 : < 340 : is_array<Up>::value, 341 : typename remove_extent<Up>::type*, 342 : typename conditional 343 : < 344 : is_function<Up>::value, 345 : typename add_pointer<Up>::type, 346 : typename remove_cv<Up>::type 347 : >::type 348 : >::type type; 349 : }; 350 : #endif 351 : 352 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 353 : template <class T> 354 : typename decay<T>::type 355 357 : decay_copy(T&& t) 356 : { 357 357 : return boost::forward<T>(t); 358 : } 359 : typedef void (*void_fct_ptr)(); 360 : 361 : // inline void_fct_ptr 362 : // decay_copy(void (&t)()) 363 : // { 364 : // return &t; 365 : // } 366 : #else 367 : template <class T> 368 : typename decay<T>::type 369 : decay_copy(BOOST_THREAD_FWD_REF(T) t) 370 : { 371 : return boost::forward<T>(t); 372 : } 373 : #endif 374 : } 375 : } 376 : 377 : #include <boost/config/abi_suffix.hpp> 378 : 379 : #endif