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