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; thread_move_tboost::detail::thread_move_t42 explicit thread_move_t(T& t_): 43 t(t_) 44 {} 45 operator *boost::detail::thread_move_t46 T& operator*() const 47 { 48 return t; 49 } 50 operator ->boost::detail::thread_move_t51 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> move(T & 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> move(boost::detail::thread_move_t<T> 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) make_rv_ref(T v)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 decay_copy(T && t)355 decay_copy(T&& t) 356 { 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 decay_copy(BOOST_THREAD_FWD_REF (T)t)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 380