blob: 103717821da9b8f83899b983c5b794235ff268d7 [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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070016#ifndef NDNBOOST_MOVE_CORE_HPP
17#define NDNBOOST_MOVE_CORE_HPP
Jeff Thompsona28eed82013-08-22 16:21:10 -070018
19#include <ndnboost/move/detail/config_begin.hpp>
20
Jeff Thompson3d613fd2013-10-15 15:39:04 -070021#ifdef NDNBOOST_NO_CXX11_DELETED_FUNCTIONS
22 #define NDNBOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
Jeff Thompsona28eed82013-08-22 16:21:10 -070023 private:\
24 TYPE(TYPE &);\
25 TYPE& operator=(TYPE &);\
26 //
27#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070028 #define NDNBOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
Jeff Thompsona28eed82013-08-22 16:21:10 -070029 public:\
30 TYPE(TYPE const &) = delete;\
31 TYPE& operator=(TYPE const &) = delete;\
32 private:\
33 //
Jeff Thompson3d613fd2013-10-15 15:39:04 -070034#endif //NDNBOOST_NO_CXX11_DELETED_FUNCTIONS
Jeff Thompsona28eed82013-08-22 16:21:10 -070035
Jeff Thompson3d613fd2013-10-15 15:39:04 -070036#if defined(NDNBOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
Jeff Thompsona28eed82013-08-22 16:21:10 -070037
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)
Jeff Thompson3d613fd2013-10-15 15:39:04 -070042 #define NDNBOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
Jeff Thompsona28eed82013-08-22 16:21:10 -070043 #else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070044 #define NDNBOOST_MOVE_ATTRIBUTE_MAY_ALIAS
Jeff Thompsona28eed82013-08-22 16:21:10 -070045 #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&);
Jeff Thompson3d613fd2013-10-15 15:39:04 -070066 } NDNBOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
Jeff Thompsona28eed82013-08-22 16:21:10 -070067
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700116 #define NDNBOOST_RV_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700117 ::ndnboost::rv< TYPE >& \
118 //
119
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700120 #define NDNBOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700121 ::ndnboost::rv< TYPE<ARG1, ARG2> >& \
122 //
123
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700124 #define NDNBOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700125 ::ndnboost::rv< TYPE<ARG1, ARG2, ARG3> >& \
126 //
127
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700128 #define NDNBOOST_RV_REF_BEG\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700129 ::ndnboost::rv< \
130 //
131
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700132 #define NDNBOOST_RV_REF_END\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700133 >& \
134 //
135
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700136 #define NDNBOOST_FWD_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700137 const TYPE & \
138 //
139
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700140 #define NDNBOOST_COPY_ASSIGN_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700141 const ::ndnboost::rv< TYPE >& \
142 //
143
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700144 #define NDNBOOST_COPY_ASSIGN_REF_BEG \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700145 const ::ndnboost::rv< \
146 //
147
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700148 #define NDNBOOST_COPY_ASSIGN_REF_END \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700149 >& \
150 //
151
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700152 #define NDNBOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700153 const ::ndnboost::rv< TYPE<ARG1, ARG2> >& \
154 //
155
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700156 #define NDNBOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700157 const ::ndnboost::rv< TYPE<ARG1, ARG2, ARG3> >& \
158 //
159
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700160 #define NDNBOOST_CATCH_CONST_RLVALUE(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700161 const ::ndnboost::rv< TYPE >& \
162 //
163
164 //////////////////////////////////////////////////////////////////////////////
165 //
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700166 // NDNBOOST_MOVABLE_BUT_NOT_COPYABLE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700167 //
168 //////////////////////////////////////////////////////////////////////////////
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700169 #define NDNBOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
170 NDNBOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700171 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 //
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700181 // NDNBOOST_COPYABLE_AND_MOVABLE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700182 //
183 //////////////////////////////////////////////////////////////////////////////
184
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700185 #define NDNBOOST_COPYABLE_AND_MOVABLE(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700186 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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700197 #define NDNBOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700198 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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700206#else //NDNBOOST_NO_CXX11_RVALUE_REFERENCES
Jeff Thompsona28eed82013-08-22 16:21:10 -0700207
208 //Compiler workaround detection
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700209 #if !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700210 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
211 //Pre-standard rvalue binding rules
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700212 #define NDNBOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
Jeff Thompsona28eed82013-08-22 16:21:10 -0700213 #elif defined(_MSC_VER) && (_MSC_VER == 1600)
214 //Standard rvalue binding rules but with some bugs
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700215 #define NDNBOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
Jeff Thompsona28eed82013-08-22 16:21:10 -0700216 //Use standard library for MSVC to avoid namespace issues as
217 //some move calls in the STL are not fully qualified.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700218 //#define NDNBOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700219 #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.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700225 #define NDNBOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
226 NDNBOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700227 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.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700234 #define NDNBOOST_COPYABLE_AND_MOVABLE(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700235 //
236
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700237 #if !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
238 #define NDNBOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700239 //
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700240 #endif //#if !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700241
242 namespace ndnboost {
243
244 //!This trait yields to a compile-time true boolean if T was marked as
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700245 //!NDNBOOST_MOVABLE_BUT_NOT_COPYABLE or NDNBOOST_COPYABLE_AND_MOVABLE and
Jeff Thompsona28eed82013-08-22 16:21:10 -0700246 //!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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700257 //!NDNBOOST_COPYABLE_AND_MOVABLE or NDNBOOST_MOVABLE_BUT_NOT_COPYABLE
258 #define NDNBOOST_RV_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700259 TYPE && \
260 //
261
262 //!This macro is used to achieve portable syntax in move
263 //!constructors and assignments for template classes marked as
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700264 //!NDNBOOST_COPYABLE_AND_MOVABLE or NDNBOOST_MOVABLE_BUT_NOT_COPYABLE.
Jeff Thompsona28eed82013-08-22 16:21:10 -0700265 //!As macros have problems with comma-separatd template arguments,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700266 //!the template argument must be preceded with NDNBOOST_RV_REF_START
267 //!and ended with NDNBOOST_RV_REF_END
268 #define NDNBOOST_RV_REF_BEG\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700269 \
270 //
271
272 //!This macro is used to achieve portable syntax in move
273 //!constructors and assignments for template classes marked as
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700274 //!NDNBOOST_COPYABLE_AND_MOVABLE or NDNBOOST_MOVABLE_BUT_NOT_COPYABLE.
Jeff Thompsona28eed82013-08-22 16:21:10 -0700275 //!As macros have problems with comma-separatd template arguments,
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700276 //!the template argument must be preceded with NDNBOOST_RV_REF_START
277 //!and ended with NDNBOOST_RV_REF_END
278 #define NDNBOOST_RV_REF_END\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700279 && \
280
281 //!This macro is used to achieve portable syntax in copy
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700282 //!assignment for classes marked as NDNBOOST_COPYABLE_AND_MOVABLE.
283 #define NDNBOOST_COPY_ASSIGN_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700284 const TYPE & \
285 //
286
287 //! This macro is used to implement portable perfect forwarding
288 //! as explained in the documentation.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700289 #define NDNBOOST_FWD_REF(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700290 TYPE && \
291 //
292
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700293 #if !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700294 /// @cond
295
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700296 #define NDNBOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700297 TYPE<ARG1, ARG2> && \
298 //
299
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700300 #define NDNBOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700301 TYPE<ARG1, ARG2, ARG3> && \
302 //
303
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700304 #define NDNBOOST_COPY_ASSIGN_REF_BEG \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700305 const \
306 //
307
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700308 #define NDNBOOST_COPY_ASSIGN_REF_END \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700309 & \
310 //
311
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700312 #define NDNBOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700313 const TYPE<ARG1, ARG2> & \
314 //
315
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700316 #define NDNBOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700317 const TYPE<ARG1, ARG2, ARG3>& \
318 //
319
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700320 #define NDNBOOST_CATCH_CONST_RLVALUE(TYPE)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700321 const TYPE & \
322 //
323
324 /// @endcond
325
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700326 #endif //#if !defined(NDNBOOST_MOVE_DOXYGEN_INVOKED)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700327
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700328#endif //NDNBOOST_NO_CXX11_RVALUE_REFERENCES
Jeff Thompsona28eed82013-08-22 16:21:10 -0700329
330#include <ndnboost/move/detail/config_end.hpp>
331
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700332#endif //#ifndef NDNBOOST_MOVE_CORE_HPP