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

source code of boost/libs/move/include/boost/move/core.hpp