blob: 92e47eccbd3087c5593c0af128767d0ace52fc03 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001//////////////////////////////////////////////////////////////////////////////
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 core.hpp
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#include <ndnboost/move/detail/config_begin.hpp>
20
21#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
22 #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
23 private:\
24 TYPE(TYPE &);\
25 TYPE& operator=(TYPE &);\
26 //
27#else
28 #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
29 public:\
30 TYPE(TYPE const &) = delete;\
31 TYPE& operator=(TYPE const &) = delete;\
32 private:\
33 //
34#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
35
36#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
37
38 #include <ndnboost/move/detail/meta_utils.hpp>
39
40 //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
41 #if defined(__GNUC__) && (__GNUC__ >= 4)
42 #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
43 #else
44 #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
45 #endif
46
47 namespace ndnboost {
48
49 //////////////////////////////////////////////////////////////////////////////
50 //
51 // struct rv
52 //
53 //////////////////////////////////////////////////////////////////////////////
54 template <class T>
55 class rv
56 : public ::ndnboost::move_detail::if_c
57 < ::ndnboost::move_detail::is_class_or_union<T>::value
58 , T
59 , ::ndnboost::move_detail::empty
60 >::type
61 {
62 rv();
63 ~rv();
64 rv(rv const&);
65 void operator=(rv const&);
66 } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
67
68
69 //////////////////////////////////////////////////////////////////////////////
70 //
71 // move_detail::is_rv
72 //
73 //////////////////////////////////////////////////////////////////////////////
74
75 namespace move_detail {
76
77 template <class T>
78 struct is_rv
79 : ::ndnboost::move_detail::integral_constant<bool, false>
80 {};
81
82 template <class T>
83 struct is_rv< rv<T> >
84 : ::ndnboost::move_detail::integral_constant<bool, true>
85 {};
86
87 template <class T>
88 struct is_rv< const rv<T> >
89 : ::ndnboost::move_detail::integral_constant<bool, true>
90 {};
91
92 } //namespace move_detail {
93
94 //////////////////////////////////////////////////////////////////////////////
95 //
96 // has_move_emulation_enabled
97 //
98 //////////////////////////////////////////////////////////////////////////////
99 template<class T>
100 struct has_move_emulation_enabled
101 : ::ndnboost::move_detail::is_convertible< T, ::ndnboost::rv<T>& >
102 {};
103
104 template<class T>
105 struct has_move_emulation_enabled<T&>
106 : ::ndnboost::move_detail::integral_constant<bool, false>
107 {};
108
109 template<class T>
110 struct has_move_emulation_enabled< ::ndnboost::rv<T> >
111 : ::ndnboost::move_detail::integral_constant<bool, false>
112 {};
113
114 } //namespace ndnboost {
115
116 #define BOOST_RV_REF(TYPE)\
117 ::ndnboost::rv< TYPE >& \
118 //
119
120 #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
121 ::ndnboost::rv< TYPE<ARG1, ARG2> >& \
122 //
123
124 #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
125 ::ndnboost::rv< TYPE<ARG1, ARG2, ARG3> >& \
126 //
127
128 #define BOOST_RV_REF_BEG\
129 ::ndnboost::rv< \
130 //
131
132 #define BOOST_RV_REF_END\
133 >& \
134 //
135
136 #define BOOST_FWD_REF(TYPE)\
137 const TYPE & \
138 //
139
140 #define BOOST_COPY_ASSIGN_REF(TYPE)\
141 const ::ndnboost::rv< TYPE >& \
142 //
143
144 #define BOOST_COPY_ASSIGN_REF_BEG \
145 const ::ndnboost::rv< \
146 //
147
148 #define BOOST_COPY_ASSIGN_REF_END \
149 >& \
150 //
151
152 #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
153 const ::ndnboost::rv< TYPE<ARG1, ARG2> >& \
154 //
155
156 #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
157 const ::ndnboost::rv< TYPE<ARG1, ARG2, ARG3> >& \
158 //
159
160 #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
161 const ::ndnboost::rv< TYPE >& \
162 //
163
164 //////////////////////////////////////////////////////////////////////////////
165 //
166 // BOOST_MOVABLE_BUT_NOT_COPYABLE
167 //
168 //////////////////////////////////////////////////////////////////////////////
169 #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
170 BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
171 public:\
172 operator ::ndnboost::rv<TYPE>&() \
173 { return *static_cast< ::ndnboost::rv<TYPE>* >(this); }\
174 operator const ::ndnboost::rv<TYPE>&() const \
175 { return *static_cast<const ::ndnboost::rv<TYPE>* >(this); }\
176 private:\
177 //
178
179 //////////////////////////////////////////////////////////////////////////////
180 //
181 // BOOST_COPYABLE_AND_MOVABLE
182 //
183 //////////////////////////////////////////////////////////////////////////////
184
185 #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
186 public:\
187 TYPE& operator=(TYPE &t)\
188 { this->operator=(static_cast<const ::ndnboost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
189 public:\
190 operator ::ndnboost::rv<TYPE>&() \
191 { return *static_cast< ::ndnboost::rv<TYPE>* >(this); }\
192 operator const ::ndnboost::rv<TYPE>&() const \
193 { return *static_cast<const ::ndnboost::rv<TYPE>* >(this); }\
194 private:\
195 //
196
197 #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
198 public:\
199 operator ::ndnboost::rv<TYPE>&() \
200 { return *static_cast< ::ndnboost::rv<TYPE>* >(this); }\
201 operator const ::ndnboost::rv<TYPE>&() const \
202 { return *static_cast<const ::ndnboost::rv<TYPE>* >(this); }\
203 private:\
204 //
205
206#else //BOOST_NO_CXX11_RVALUE_REFERENCES
207
208 //Compiler workaround detection
209 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
210 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
211 //Pre-standard rvalue binding rules
212 #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
213 #elif defined(_MSC_VER) && (_MSC_VER == 1600)
214 //Standard rvalue binding rules but with some bugs
215 #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
216 //Use standard library for MSVC to avoid namespace issues as
217 //some move calls in the STL are not fully qualified.
218 //#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
219 #endif
220 #endif
221
222 //! This macro marks a type as movable but not copyable, disabling copy construction
223 //! and assignment. The user will need to write a move constructor/assignment as explained
224 //! in the documentation to fully write a movable but not copyable class.
225 #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
226 BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
227 public:\
228 typedef int boost_move_emulation_t;\
229 //
230
231 //! This macro marks a type as copyable and movable.
232 //! The user will need to write a move constructor/assignment and a copy assignment
233 //! as explained in the documentation to fully write a copyable and movable class.
234 #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
235 //
236
237 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
238 #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
239 //
240 #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
241
242 namespace ndnboost {
243
244 //!This trait yields to a compile-time true boolean if T was marked as
245 //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
246 //!rvalue references are not available on the platform. False otherwise.
247 template<class T>
248 struct has_move_emulation_enabled
249 {
250 static const bool value = false;
251 };
252
253 } //namespace ndnboost{
254
255 //!This macro is used to achieve portable syntax in move
256 //!constructors and assignments for classes marked as
257 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
258 #define BOOST_RV_REF(TYPE)\
259 TYPE && \
260 //
261
262 //!This macro is used to achieve portable syntax in move
263 //!constructors and assignments for template classes marked as
264 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
265 //!As macros have problems with comma-separatd template arguments,
266 //!the template argument must be preceded with BOOST_RV_REF_START
267 //!and ended with BOOST_RV_REF_END
268 #define BOOST_RV_REF_BEG\
269 \
270 //
271
272 //!This macro is used to achieve portable syntax in move
273 //!constructors and assignments for template classes marked as
274 //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
275 //!As macros have problems with comma-separatd template arguments,
276 //!the template argument must be preceded with BOOST_RV_REF_START
277 //!and ended with BOOST_RV_REF_END
278 #define BOOST_RV_REF_END\
279 && \
280
281 //!This macro is used to achieve portable syntax in copy
282 //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
283 #define BOOST_COPY_ASSIGN_REF(TYPE)\
284 const TYPE & \
285 //
286
287 //! This macro is used to implement portable perfect forwarding
288 //! as explained in the documentation.
289 #define BOOST_FWD_REF(TYPE)\
290 TYPE && \
291 //
292
293 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
294 /// @cond
295
296 #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
297 TYPE<ARG1, ARG2> && \
298 //
299
300 #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
301 TYPE<ARG1, ARG2, ARG3> && \
302 //
303
304 #define BOOST_COPY_ASSIGN_REF_BEG \
305 const \
306 //
307
308 #define BOOST_COPY_ASSIGN_REF_END \
309 & \
310 //
311
312 #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
313 const TYPE<ARG1, ARG2> & \
314 //
315
316 #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
317 const TYPE<ARG1, ARG2, ARG3>& \
318 //
319
320 #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
321 const TYPE & \
322 //
323
324 /// @endcond
325
326 #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
327
328#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
329
330#include <ndnboost/move/detail/config_end.hpp>
331
332#endif //#ifndef BOOST_MOVE_CORE_HPP