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