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
33namespace 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) \
169template <> \
170struct enable_move_utility_emulation< TYPE > \
171{ \
172 static const bool value = false; \
173};
174
175#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
176template <typename T> \
177struct enable_move_utility_emulation<
178
179#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
180template <typename T1, typename T2> \
181struct enable_move_utility_emulation<
182
183#define BOOST_THREAD_DCL_MOVABLE_END > \
184{ \
185 static const bool value = false; \
186};
187
188#endif
189
190namespace boost
191{
192namespace 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
283namespace 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