Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2012-2012.
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
5 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 // See http://www.boost.org/libs/move for documentation.
|
Chris@16
|
9 //
|
Chris@16
|
10 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
11
|
Chris@101
|
12 //! \file
|
Chris@16
|
13 //! This header implements macros to define movable classes and
|
Chris@16
|
14 //! move-aware functions
|
Chris@16
|
15
|
Chris@16
|
16 #ifndef BOOST_MOVE_CORE_HPP
|
Chris@16
|
17 #define BOOST_MOVE_CORE_HPP
|
Chris@16
|
18
|
Chris@101
|
19 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
20 # include <boost/config.hpp>
|
Chris@101
|
21 #endif
|
Chris@101
|
22 #
|
Chris@101
|
23 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
24 # pragma once
|
Chris@101
|
25 #endif
|
Chris@101
|
26
|
Chris@16
|
27 #include <boost/move/detail/config_begin.hpp>
|
Chris@101
|
28 #include <boost/move/detail/workaround.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 //boost_move_no_copy_constructor_or_assign typedef
|
Chris@16
|
31 //used to detect noncopyable types for other Boost libraries.
|
Chris@101
|
32 #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
33 #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
Chris@16
|
34 private:\
|
Chris@16
|
35 TYPE(TYPE &);\
|
Chris@16
|
36 TYPE& operator=(TYPE &);\
|
Chris@16
|
37 public:\
|
Chris@16
|
38 typedef int boost_move_no_copy_constructor_or_assign; \
|
Chris@16
|
39 private:\
|
Chris@16
|
40 //
|
Chris@16
|
41 #else
|
Chris@16
|
42 #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
Chris@16
|
43 public:\
|
Chris@16
|
44 TYPE(TYPE const &) = delete;\
|
Chris@16
|
45 TYPE& operator=(TYPE const &) = delete;\
|
Chris@16
|
46 public:\
|
Chris@16
|
47 typedef int boost_move_no_copy_constructor_or_assign; \
|
Chris@16
|
48 private:\
|
Chris@16
|
49 //
|
Chris@16
|
50 #endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
|
Chris@16
|
51
|
Chris@16
|
52 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@16
|
53
|
Chris@101
|
54 #include <boost/move/detail/type_traits.hpp>
|
Chris@16
|
55
|
Chris@16
|
56 //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
|
Chris@101
|
57 #if defined(__GNUC__) && (__GNUC__ >= 4) && \
|
Chris@101
|
58 (\
|
Chris@101
|
59 defined(BOOST_GCC) || \
|
Chris@101
|
60 (defined(BOOST_INTEL) && (BOOST_INTEL_CXX_VERSION >= 1300)) \
|
Chris@101
|
61 )
|
Chris@16
|
62 #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
|
Chris@16
|
63 #else
|
Chris@16
|
64 #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
|
Chris@16
|
65 #endif
|
Chris@16
|
66
|
Chris@16
|
67 namespace boost {
|
Chris@16
|
68
|
Chris@16
|
69 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
70 //
|
Chris@16
|
71 // struct rv
|
Chris@16
|
72 //
|
Chris@16
|
73 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
74 template <class T>
|
Chris@16
|
75 class rv
|
Chris@16
|
76 : public ::boost::move_detail::if_c
|
Chris@101
|
77 < ::boost::move_detail::is_class<T>::value
|
Chris@16
|
78 , T
|
Chris@101
|
79 , ::boost::move_detail::nat
|
Chris@16
|
80 >::type
|
Chris@16
|
81 {
|
Chris@16
|
82 rv();
|
Chris@101
|
83 ~rv() throw();
|
Chris@16
|
84 rv(rv const&);
|
Chris@16
|
85 void operator=(rv const&);
|
Chris@16
|
86 } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
|
Chris@16
|
87
|
Chris@16
|
88
|
Chris@16
|
89 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
90 //
|
Chris@101
|
91 // is_rv
|
Chris@16
|
92 //
|
Chris@16
|
93 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
94
|
Chris@16
|
95 namespace move_detail {
|
Chris@16
|
96
|
Chris@16
|
97 template <class T>
|
Chris@16
|
98 struct is_rv
|
Chris@101
|
99 //Derive from integral constant because some Boost code assummes it has
|
Chris@101
|
100 //a "type" internal typedef
|
Chris@101
|
101 : integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
|
Chris@16
|
102 {};
|
Chris@16
|
103
|
Chris@16
|
104 } //namespace move_detail {
|
Chris@16
|
105
|
Chris@16
|
106 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
107 //
|
Chris@16
|
108 // has_move_emulation_enabled
|
Chris@16
|
109 //
|
Chris@16
|
110 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
111 template<class T>
|
Chris@16
|
112 struct has_move_emulation_enabled
|
Chris@101
|
113 : ::boost::move_detail::has_move_emulation_enabled_impl<T>
|
Chris@16
|
114 {};
|
Chris@16
|
115
|
Chris@16
|
116 } //namespace boost {
|
Chris@16
|
117
|
Chris@16
|
118 #define BOOST_RV_REF(TYPE)\
|
Chris@16
|
119 ::boost::rv< TYPE >& \
|
Chris@16
|
120 //
|
Chris@16
|
121
|
Chris@16
|
122 #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
Chris@16
|
123 ::boost::rv< TYPE<ARG1, ARG2> >& \
|
Chris@16
|
124 //
|
Chris@16
|
125
|
Chris@16
|
126 #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
Chris@16
|
127 ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
|
Chris@16
|
128 //
|
Chris@16
|
129
|
Chris@16
|
130 #define BOOST_RV_REF_BEG\
|
Chris@16
|
131 ::boost::rv< \
|
Chris@16
|
132 //
|
Chris@16
|
133
|
Chris@16
|
134 #define BOOST_RV_REF_END\
|
Chris@16
|
135 >& \
|
Chris@16
|
136 //
|
Chris@16
|
137
|
Chris@16
|
138 #define BOOST_FWD_REF(TYPE)\
|
Chris@16
|
139 const TYPE & \
|
Chris@16
|
140 //
|
Chris@16
|
141
|
Chris@16
|
142 #define BOOST_COPY_ASSIGN_REF(TYPE)\
|
Chris@16
|
143 const ::boost::rv< TYPE >& \
|
Chris@16
|
144 //
|
Chris@16
|
145
|
Chris@16
|
146 #define BOOST_COPY_ASSIGN_REF_BEG \
|
Chris@16
|
147 const ::boost::rv< \
|
Chris@16
|
148 //
|
Chris@16
|
149
|
Chris@16
|
150 #define BOOST_COPY_ASSIGN_REF_END \
|
Chris@16
|
151 >& \
|
Chris@16
|
152 //
|
Chris@16
|
153
|
Chris@16
|
154 #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
Chris@16
|
155 const ::boost::rv< TYPE<ARG1, ARG2> >& \
|
Chris@16
|
156 //
|
Chris@16
|
157
|
Chris@16
|
158 #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
Chris@16
|
159 const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
|
Chris@16
|
160 //
|
Chris@16
|
161
|
Chris@16
|
162 #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
|
Chris@16
|
163 const ::boost::rv< TYPE >& \
|
Chris@16
|
164 //
|
Chris@16
|
165
|
Chris@101
|
166 namespace boost {
|
Chris@101
|
167 namespace move_detail {
|
Chris@101
|
168
|
Chris@101
|
169 template <class Ret, class T>
|
Chris@101
|
170 inline typename ::boost::move_detail::enable_if_c
|
Chris@101
|
171 < ::boost::move_detail::is_lvalue_reference<Ret>::value ||
|
Chris@101
|
172 !::boost::has_move_emulation_enabled<T>::value
|
Chris@101
|
173 , T&>::type
|
Chris@101
|
174 move_return(T& x) BOOST_NOEXCEPT
|
Chris@101
|
175 {
|
Chris@101
|
176 return x;
|
Chris@101
|
177 }
|
Chris@101
|
178
|
Chris@101
|
179 template <class Ret, class T>
|
Chris@101
|
180 inline typename ::boost::move_detail::enable_if_c
|
Chris@101
|
181 < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
Chris@101
|
182 ::boost::has_move_emulation_enabled<T>::value
|
Chris@101
|
183 , ::boost::rv<T>&>::type
|
Chris@101
|
184 move_return(T& x) BOOST_NOEXCEPT
|
Chris@101
|
185 {
|
Chris@101
|
186 return *static_cast< ::boost::rv<T>* >(::boost::move_detail::addressof(x));
|
Chris@101
|
187 }
|
Chris@101
|
188
|
Chris@101
|
189 template <class Ret, class T>
|
Chris@101
|
190 inline typename ::boost::move_detail::enable_if_c
|
Chris@101
|
191 < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
Chris@101
|
192 ::boost::has_move_emulation_enabled<T>::value
|
Chris@101
|
193 , ::boost::rv<T>&>::type
|
Chris@101
|
194 move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
|
Chris@101
|
195 {
|
Chris@101
|
196 return x;
|
Chris@101
|
197 }
|
Chris@101
|
198
|
Chris@101
|
199 } //namespace move_detail {
|
Chris@101
|
200 } //namespace boost {
|
Chris@101
|
201
|
Chris@101
|
202 #define BOOST_MOVE_RET(RET_TYPE, REF)\
|
Chris@101
|
203 boost::move_detail::move_return< RET_TYPE >(REF)
|
Chris@101
|
204 //
|
Chris@101
|
205
|
Chris@101
|
206 #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
|
Chris@101
|
207 ::boost::move((BASE_TYPE&)(ARG))
|
Chris@101
|
208 //
|
Chris@101
|
209
|
Chris@16
|
210 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
211 //
|
Chris@16
|
212 // BOOST_MOVABLE_BUT_NOT_COPYABLE
|
Chris@16
|
213 //
|
Chris@16
|
214 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
215 #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
|
Chris@16
|
216 BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
|
Chris@16
|
217 public:\
|
Chris@16
|
218 operator ::boost::rv<TYPE>&() \
|
Chris@16
|
219 { return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
220 operator const ::boost::rv<TYPE>&() const \
|
Chris@16
|
221 { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
222 private:\
|
Chris@16
|
223 //
|
Chris@16
|
224
|
Chris@16
|
225 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
226 //
|
Chris@16
|
227 // BOOST_COPYABLE_AND_MOVABLE
|
Chris@16
|
228 //
|
Chris@16
|
229 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
230
|
Chris@16
|
231 #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
|
Chris@16
|
232 public:\
|
Chris@16
|
233 TYPE& operator=(TYPE &t)\
|
Chris@16
|
234 { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
|
Chris@16
|
235 public:\
|
Chris@16
|
236 operator ::boost::rv<TYPE>&() \
|
Chris@16
|
237 { return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
238 operator const ::boost::rv<TYPE>&() const \
|
Chris@16
|
239 { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
240 private:\
|
Chris@16
|
241 //
|
Chris@16
|
242
|
Chris@16
|
243 #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
|
Chris@16
|
244 public:\
|
Chris@16
|
245 operator ::boost::rv<TYPE>&() \
|
Chris@16
|
246 { return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
247 operator const ::boost::rv<TYPE>&() const \
|
Chris@16
|
248 { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
Chris@16
|
249 private:\
|
Chris@16
|
250 //
|
Chris@16
|
251
|
Chris@101
|
252 namespace boost{
|
Chris@101
|
253 namespace move_detail{
|
Chris@101
|
254
|
Chris@101
|
255 template< class T>
|
Chris@101
|
256 struct forward_type
|
Chris@101
|
257 { typedef const T &type; };
|
Chris@101
|
258
|
Chris@101
|
259 template< class T>
|
Chris@101
|
260 struct forward_type< boost::rv<T> >
|
Chris@101
|
261 { typedef T type; };
|
Chris@101
|
262
|
Chris@101
|
263 }}
|
Chris@101
|
264
|
Chris@16
|
265 #else //BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
266
|
Chris@16
|
267 //! This macro marks a type as movable but not copyable, disabling copy construction
|
Chris@16
|
268 //! and assignment. The user will need to write a move constructor/assignment as explained
|
Chris@16
|
269 //! in the documentation to fully write a movable but not copyable class.
|
Chris@16
|
270 #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
|
Chris@16
|
271 BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
|
Chris@16
|
272 public:\
|
Chris@16
|
273 typedef int boost_move_emulation_t;\
|
Chris@16
|
274 //
|
Chris@16
|
275
|
Chris@16
|
276 //! This macro marks a type as copyable and movable.
|
Chris@16
|
277 //! The user will need to write a move constructor/assignment and a copy assignment
|
Chris@16
|
278 //! as explained in the documentation to fully write a copyable and movable class.
|
Chris@16
|
279 #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
|
Chris@16
|
280 //
|
Chris@16
|
281
|
Chris@16
|
282 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@16
|
283 #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
|
Chris@16
|
284 //
|
Chris@16
|
285 #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@16
|
286
|
Chris@16
|
287 namespace boost {
|
Chris@16
|
288
|
Chris@16
|
289 //!This trait yields to a compile-time true boolean if T was marked as
|
Chris@16
|
290 //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
|
Chris@16
|
291 //!rvalue references are not available on the platform. False otherwise.
|
Chris@16
|
292 template<class T>
|
Chris@16
|
293 struct has_move_emulation_enabled
|
Chris@16
|
294 {
|
Chris@16
|
295 static const bool value = false;
|
Chris@16
|
296 };
|
Chris@16
|
297
|
Chris@16
|
298 } //namespace boost{
|
Chris@16
|
299
|
Chris@16
|
300 //!This macro is used to achieve portable syntax in move
|
Chris@16
|
301 //!constructors and assignments for classes marked as
|
Chris@16
|
302 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
|
Chris@16
|
303 #define BOOST_RV_REF(TYPE)\
|
Chris@16
|
304 TYPE && \
|
Chris@16
|
305 //
|
Chris@16
|
306
|
Chris@16
|
307 //!This macro is used to achieve portable syntax in move
|
Chris@16
|
308 //!constructors and assignments for template classes marked as
|
Chris@16
|
309 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
|
Chris@101
|
310 //!As macros have problems with comma-separated template arguments,
|
Chris@101
|
311 //!the template argument must be preceded with BOOST_RV_REF_BEG
|
Chris@16
|
312 //!and ended with BOOST_RV_REF_END
|
Chris@16
|
313 #define BOOST_RV_REF_BEG\
|
Chris@16
|
314 \
|
Chris@16
|
315 //
|
Chris@16
|
316
|
Chris@16
|
317 //!This macro is used to achieve portable syntax in move
|
Chris@16
|
318 //!constructors and assignments for template classes marked as
|
Chris@16
|
319 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
|
Chris@101
|
320 //!As macros have problems with comma-separated template arguments,
|
Chris@101
|
321 //!the template argument must be preceded with BOOST_RV_REF_BEG
|
Chris@16
|
322 //!and ended with BOOST_RV_REF_END
|
Chris@16
|
323 #define BOOST_RV_REF_END\
|
Chris@16
|
324 && \
|
Chris@16
|
325
|
Chris@16
|
326 //!This macro is used to achieve portable syntax in copy
|
Chris@16
|
327 //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
|
Chris@16
|
328 #define BOOST_COPY_ASSIGN_REF(TYPE)\
|
Chris@16
|
329 const TYPE & \
|
Chris@16
|
330 //
|
Chris@16
|
331
|
Chris@16
|
332 //! This macro is used to implement portable perfect forwarding
|
Chris@16
|
333 //! as explained in the documentation.
|
Chris@16
|
334 #define BOOST_FWD_REF(TYPE)\
|
Chris@16
|
335 TYPE && \
|
Chris@16
|
336 //
|
Chris@16
|
337
|
Chris@16
|
338 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@16
|
339
|
Chris@16
|
340 #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
Chris@16
|
341 TYPE<ARG1, ARG2> && \
|
Chris@16
|
342 //
|
Chris@16
|
343
|
Chris@16
|
344 #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
Chris@16
|
345 TYPE<ARG1, ARG2, ARG3> && \
|
Chris@16
|
346 //
|
Chris@16
|
347
|
Chris@16
|
348 #define BOOST_COPY_ASSIGN_REF_BEG \
|
Chris@16
|
349 const \
|
Chris@16
|
350 //
|
Chris@16
|
351
|
Chris@16
|
352 #define BOOST_COPY_ASSIGN_REF_END \
|
Chris@16
|
353 & \
|
Chris@16
|
354 //
|
Chris@16
|
355
|
Chris@16
|
356 #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
Chris@16
|
357 const TYPE<ARG1, ARG2> & \
|
Chris@16
|
358 //
|
Chris@16
|
359
|
Chris@16
|
360 #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
Chris@16
|
361 const TYPE<ARG1, ARG2, ARG3>& \
|
Chris@16
|
362 //
|
Chris@16
|
363
|
Chris@16
|
364 #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
|
Chris@16
|
365 const TYPE & \
|
Chris@16
|
366 //
|
Chris@16
|
367
|
Chris@101
|
368 #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@16
|
369
|
Chris@101
|
370 #if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@101
|
371
|
Chris@101
|
372 //!This macro is used to achieve portable move return semantics.
|
Chris@101
|
373 //!The C++11 Standard allows implicit move returns when the object to be returned
|
Chris@101
|
374 //!is designated by a lvalue and:
|
Chris@101
|
375 //! - The criteria for elision of a copy operation are met OR
|
Chris@101
|
376 //! - The criteria would be met save for the fact that the source object is a function parameter
|
Chris@101
|
377 //!
|
Chris@101
|
378 //!For C++11 conforming compilers this macros only yields to REF:
|
Chris@101
|
379 //! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
|
Chris@101
|
380 //!
|
Chris@101
|
381 //!For compilers without rvalue references
|
Chris@101
|
382 //!this macro does an explicit move if the move emulation is activated
|
Chris@101
|
383 //!and the return type (RET_TYPE) is not a reference.
|
Chris@101
|
384 //!
|
Chris@101
|
385 //!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
|
Chris@101
|
386 //!an explicit move is performed if RET_TYPE is not a reference.
|
Chris@101
|
387 //!
|
Chris@101
|
388 //! <b>Caution</b>: When using this macro in non-conforming or C++03
|
Chris@101
|
389 //!compilers, a move will be performed even if the C++11 standard does not allow it
|
Chris@101
|
390 //!(e.g. returning a static variable). The user is responsible for using this macro
|
Chris@101
|
391 //!only to return local objects that met C++11 criteria.
|
Chris@101
|
392 #define BOOST_MOVE_RET(RET_TYPE, REF)\
|
Chris@101
|
393 REF
|
Chris@101
|
394 //
|
Chris@101
|
395
|
Chris@101
|
396 #else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@101
|
397
|
Chris@101
|
398 #include <boost/move/detail/meta_utils.hpp>
|
Chris@101
|
399
|
Chris@101
|
400 namespace boost {
|
Chris@101
|
401 namespace move_detail {
|
Chris@101
|
402
|
Chris@101
|
403 template <class Ret, class T>
|
Chris@101
|
404 inline typename ::boost::move_detail::enable_if_c
|
Chris@101
|
405 < ::boost::move_detail::is_lvalue_reference<Ret>::value
|
Chris@101
|
406 , T&>::type
|
Chris@101
|
407 move_return(T& x) BOOST_NOEXCEPT
|
Chris@101
|
408 {
|
Chris@101
|
409 return x;
|
Chris@101
|
410 }
|
Chris@101
|
411
|
Chris@101
|
412 template <class Ret, class T>
|
Chris@101
|
413 inline typename ::boost::move_detail::enable_if_c
|
Chris@101
|
414 < !::boost::move_detail::is_lvalue_reference<Ret>::value
|
Chris@101
|
415 , Ret && >::type
|
Chris@101
|
416 move_return(T&& t) BOOST_NOEXCEPT
|
Chris@101
|
417 {
|
Chris@101
|
418 return static_cast< Ret&& >(t);
|
Chris@101
|
419 }
|
Chris@101
|
420
|
Chris@101
|
421 } //namespace move_detail {
|
Chris@101
|
422 } //namespace boost {
|
Chris@101
|
423
|
Chris@101
|
424 #define BOOST_MOVE_RET(RET_TYPE, REF)\
|
Chris@101
|
425 boost::move_detail::move_return< RET_TYPE >(REF)
|
Chris@101
|
426 //
|
Chris@101
|
427
|
Chris@101
|
428 #endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@101
|
429
|
Chris@101
|
430 //!This macro is used to achieve portable optimal move constructors.
|
Chris@101
|
431 //!
|
Chris@101
|
432 //!When implementing the move constructor, in C++03 compilers the moved-from argument must be
|
Chris@101
|
433 //!cast to the base type before calling `::boost::move()` due to rvalue reference limitations.
|
Chris@101
|
434 //!
|
Chris@101
|
435 //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
|
Chris@101
|
436 //!a base type is implicit.
|
Chris@101
|
437 #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
|
Chris@101
|
438 ::boost::move((BASE_TYPE&)(ARG))
|
Chris@101
|
439 //
|
Chris@101
|
440
|
Chris@101
|
441 namespace boost {
|
Chris@101
|
442 namespace move_detail {
|
Chris@101
|
443
|
Chris@101
|
444 template< class T> struct forward_type { typedef T type; };
|
Chris@101
|
445
|
Chris@101
|
446 }}
|
Chris@16
|
447
|
Chris@16
|
448 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
449
|
Chris@16
|
450 #include <boost/move/detail/config_end.hpp>
|
Chris@16
|
451
|
Chris@16
|
452 #endif //#ifndef BOOST_MOVE_CORE_HPP
|