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; |
44 | explicit thread_move_t(T& t_): |
45 | t(t_) |
46 | {} |
47 | |
48 | T& operator*() const |
49 | { |
50 | return t; |
51 | } |
52 | |
53 | 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> |
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> |
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_BEG2(T1, T2) \ |
98 | namespace detail { \ |
99 | template <typename T1, typename T2> \ |
100 | struct enable_move_utility_emulation_dummy_specialization< |
101 | |
102 | #define BOOST_THREAD_DCL_MOVABLE_END > \ |
103 | : integral_constant<bool, false> \ |
104 | {}; \ |
105 | } |
106 | |
107 | #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_MSVC |
108 | |
109 | #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE) |
110 | #define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) |
111 | #define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE) |
112 | #define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG |
113 | #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END |
114 | #define BOOST_THREAD_RV(V) V |
115 | #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE |
116 | #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) |
117 | #define BOOST_THREAD_DCL_MOVABLE(TYPE) |
118 | #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ |
119 | namespace detail { \ |
120 | template <typename T> \ |
121 | struct enable_move_utility_emulation_dummy_specialization< |
122 | |
123 | #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ |
124 | namespace detail { \ |
125 | template <typename T1, typename T2> \ |
126 | struct enable_move_utility_emulation_dummy_specialization< |
127 | |
128 | #define BOOST_THREAD_DCL_MOVABLE_END > \ |
129 | : integral_constant<bool, false> \ |
130 | {}; \ |
131 | } |
132 | |
133 | #else |
134 | |
135 | #if defined BOOST_THREAD_USES_MOVE |
136 | #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE) |
137 | #define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) |
138 | #define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE) |
139 | #define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG |
140 | #define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END |
141 | #define BOOST_THREAD_RV(V) V |
142 | #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) |
143 | #define BOOST_THREAD_DCL_MOVABLE(TYPE) |
144 | #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ |
145 | namespace detail { \ |
146 | template <typename T> \ |
147 | struct enable_move_utility_emulation_dummy_specialization< |
148 | |
149 | #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ |
150 | namespace detail { \ |
151 | template <typename T1, typename T2> \ |
152 | struct enable_move_utility_emulation_dummy_specialization< |
153 | |
154 | #define BOOST_THREAD_DCL_MOVABLE_END > \ |
155 | : integral_constant<bool, false> \ |
156 | {}; \ |
157 | } |
158 | |
159 | #else |
160 | |
161 | #define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) const TYPE& |
162 | #define BOOST_THREAD_RV_REF(TYPE) boost::detail::thread_move_t< TYPE > |
163 | #define BOOST_THREAD_RV_REF_BEG boost::detail::thread_move_t< |
164 | #define BOOST_THREAD_RV_REF_END > |
165 | #define BOOST_THREAD_RV(V) (*V) |
166 | #define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) |
167 | |
168 | #define BOOST_THREAD_DCL_MOVABLE(TYPE) \ |
169 | template <> \ |
170 | struct enable_move_utility_emulation< TYPE > \ |
171 | { \ |
172 | static const bool value = false; \ |
173 | }; |
174 | |
175 | #define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ |
176 | template <typename T> \ |
177 | struct enable_move_utility_emulation< |
178 | |
179 | #define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \ |
180 | template <typename T1, typename T2> \ |
181 | struct enable_move_utility_emulation< |
182 | |
183 | #define BOOST_THREAD_DCL_MOVABLE_END > \ |
184 | { \ |
185 | static const bool value = false; \ |
186 | }; |
187 | |
188 | #endif |
189 | |
190 | namespace boost |
191 | { |
192 | namespace detail |
193 | { |
194 | template <typename T> |
195 | BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) |
196 | make_rv_ref(T v) BOOST_NOEXCEPT |
197 | { |
198 | return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); |
199 | } |
200 | // template <typename T> |
201 | // BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) |
202 | // make_rv_ref(T &v) BOOST_NOEXCEPT |
203 | // { |
204 | // return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); |
205 | // } |
206 | // template <typename T> |
207 | // const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) |
208 | // make_rv_ref(T const&v) BOOST_NOEXCEPT |
209 | // { |
210 | // return (const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); |
211 | // } |
212 | } |
213 | } |
214 | |
215 | #define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE.move() |
216 | //#define BOOST_THREAD_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE) |
217 | #endif |
218 | |
219 | |
220 | #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES |
221 | |
222 | #define BOOST_THREAD_MOVABLE(TYPE) |
223 | |
224 | #define BOOST_THREAD_COPYABLE(TYPE) |
225 | |
226 | #else |
227 | |
228 | #if defined BOOST_THREAD_USES_MOVE |
229 | |
230 | #define BOOST_THREAD_MOVABLE(TYPE) \ |
231 | ::boost::rv<TYPE>& move() BOOST_NOEXCEPT \ |
232 | { \ |
233 | return *static_cast< ::boost::rv<TYPE>* >(this); \ |
234 | } \ |
235 | const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \ |
236 | { \ |
237 | return *static_cast<const ::boost::rv<TYPE>* >(this); \ |
238 | } \ |
239 | operator ::boost::rv<TYPE>&() \ |
240 | { \ |
241 | return *static_cast< ::boost::rv<TYPE>* >(this); \ |
242 | } \ |
243 | operator const ::boost::rv<TYPE>&() const \ |
244 | { \ |
245 | return *static_cast<const ::boost::rv<TYPE>* >(this); \ |
246 | }\ |
247 | |
248 | #define BOOST_THREAD_COPYABLE(TYPE) \ |
249 | TYPE& operator=(TYPE &t)\ |
250 | { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;} |
251 | |
252 | |
253 | #else |
254 | |
255 | #define BOOST_THREAD_MOVABLE(TYPE) \ |
256 | operator ::boost::detail::thread_move_t<TYPE>() BOOST_NOEXCEPT \ |
257 | { \ |
258 | return move(); \ |
259 | } \ |
260 | ::boost::detail::thread_move_t<TYPE> move() BOOST_NOEXCEPT \ |
261 | { \ |
262 | ::boost::detail::thread_move_t<TYPE> x(*this); \ |
263 | return x; \ |
264 | } \ |
265 | |
266 | #define BOOST_THREAD_COPYABLE(TYPE) |
267 | |
268 | #endif |
269 | #endif |
270 | |
271 | #define BOOST_THREAD_MOVABLE_ONLY(TYPE) \ |
272 | BOOST_THREAD_NO_COPYABLE(TYPE) \ |
273 | BOOST_THREAD_MOVABLE(TYPE) \ |
274 | typedef int boost_move_no_copy_constructor_or_assign; \ |
275 | |
276 | |
277 | #define BOOST_THREAD_COPYABLE_AND_MOVABLE(TYPE) \ |
278 | BOOST_THREAD_COPYABLE(TYPE) \ |
279 | BOOST_THREAD_MOVABLE(TYPE) \ |
280 | |
281 | |
282 | |
283 | namespace boost |
284 | { |
285 | namespace thread_detail |
286 | { |
287 | |
288 | #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES |
289 | #elif defined BOOST_THREAD_USES_MOVE |
290 | template <class T> |
291 | struct is_rv |
292 | : ::boost::move_detail::is_rv<T> |
293 | {}; |
294 | |
295 | #else |
296 | template <class T> |
297 | struct is_rv |
298 | : ::boost::integral_constant<bool, false> |
299 | {}; |
300 | |
301 | template <class T> |
302 | struct is_rv< ::boost::detail::thread_move_t<T> > |
303 | : ::boost::integral_constant<bool, true> |
304 | {}; |
305 | |
306 | template <class T> |
307 | struct is_rv< const ::boost::detail::thread_move_t<T> > |
308 | : ::boost::integral_constant<bool, true> |
309 | {}; |
310 | #endif |
311 | |
312 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
313 | template <class Tp> |
314 | struct remove_reference : boost::remove_reference<Tp> {}; |
315 | template <class Tp> |
316 | struct decay : boost::decay<Tp> {}; |
317 | #else |
318 | template <class Tp> |
319 | struct remove_reference |
320 | { |
321 | typedef Tp type; |
322 | }; |
323 | template <class Tp> |
324 | struct remove_reference<Tp&> |
325 | { |
326 | typedef Tp type; |
327 | }; |
328 | template <class Tp> |
329 | struct remove_reference< rv<Tp> > { |
330 | typedef Tp type; |
331 | }; |
332 | |
333 | template <class Tp> |
334 | struct decay |
335 | { |
336 | private: |
337 | typedef typename boost::move_detail::remove_rvalue_reference<Tp>::type Up0; |
338 | typedef typename boost::remove_reference<Up0>::type Up; |
339 | public: |
340 | typedef typename conditional |
341 | < |
342 | is_array<Up>::value, |
343 | typename remove_extent<Up>::type*, |
344 | typename conditional |
345 | < |
346 | is_function<Up>::value, |
347 | typename add_pointer<Up>::type, |
348 | typename remove_cv<Up>::type |
349 | >::type |
350 | >::type type; |
351 | }; |
352 | #endif |
353 | |
354 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
355 | template <class T> |
356 | typename decay<T>::type |
357 | decay_copy(T&& t) |
358 | { |
359 | return boost::forward<T>(t); |
360 | } |
361 | #else |
362 | template <class T> |
363 | typename decay<T>::type |
364 | decay_copy(BOOST_THREAD_FWD_REF(T) t) |
365 | { |
366 | return boost::forward<T>(t); |
367 | } |
368 | #endif |
369 | } |
370 | } |
371 | |
372 | #include <boost/config/abi_suffix.hpp> |
373 | |
374 | #endif |
375 | |