1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2010-2016. |
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 | #ifndef BOOST_MOVE_MOVE_HELPERS_HPP |
13 | #define BOOST_MOVE_MOVE_HELPERS_HPP |
14 | |
15 | #ifndef BOOST_CONFIG_HPP |
16 | # include <boost/config.hpp> |
17 | #endif |
18 | # |
19 | #if defined(BOOST_HAS_PRAGMA_ONCE) |
20 | # pragma once |
21 | #endif |
22 | |
23 | #include <boost/move/core.hpp> |
24 | #include <boost/move/utility_core.hpp> |
25 | #include <boost/move/detail/type_traits.hpp> |
26 | |
27 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
28 | |
29 | #define BOOST_MOVE_CATCH_CONST(U) \ |
30 | typename ::boost::move_detail::if_< ::boost::move_detail::is_class<U>, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type |
31 | #define BOOST_MOVE_CATCH_RVALUE(U)\ |
32 | typename ::boost::move_detail::if_< ::boost::move_detail::is_class<U>, BOOST_RV_REF(U), ::boost::move_detail::nat>::type |
33 | #define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U) |
34 | #else |
35 | #define BOOST_MOVE_CATCH_CONST(U) const U & |
36 | #define BOOST_MOVE_CATCH_RVALUE(U) U && |
37 | #define BOOST_MOVE_CATCH_FWD(U) U && |
38 | #endif |
39 | |
40 | //////////////////////////////////////// |
41 | // |
42 | // BOOST_MOVE_CONVERSION_AWARE_CATCH |
43 | // |
44 | //////////////////////////////////////// |
45 | |
46 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES |
47 | |
48 | template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class TYPE> |
49 | struct boost_move_conversion_aware_catch_1 |
50 | : public ::boost::move_detail::enable_if_and |
51 | < RETURN_VALUE |
52 | , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> |
53 | , ::boost::move_detail::is_class<TYPE> |
54 | , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM> |
55 | > |
56 | {}; |
57 | |
58 | template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class TYPE> |
59 | struct boost_move_conversion_aware_catch_2 |
60 | : public ::boost::move_detail::disable_if_or |
61 | < RETURN_VALUE |
62 | , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> |
63 | , ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM> |
64 | , ::boost::move_detail::and_ |
65 | < ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM> |
66 | , ::boost::move_detail::is_class<BOOST_MOVE_TEMPL_PARAM> |
67 | > |
68 | > |
69 | {}; |
70 | |
71 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
72 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
73 | { return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\ |
74 | \ |
75 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
76 | { return FWD_FUNCTION(::boost::move(x)); }\ |
77 | \ |
78 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(TYPE &x)\ |
79 | { return FWD_FUNCTION(const_cast<const TYPE &>(x)); }\ |
80 | // |
81 | #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN) |
82 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
83 | BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
84 | \ |
85 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
86 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\ |
87 | typename boost_move_conversion_aware_catch_1< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\ |
88 | { return FWD_FUNCTION(u); }\ |
89 | \ |
90 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
91 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\ |
92 | typename boost_move_conversion_aware_catch_2< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\ |
93 | {\ |
94 | TYPE t((u));\ |
95 | return FWD_FUNCTION(::boost::move(t));\ |
96 | }\ |
97 | // |
98 | #else |
99 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
100 | BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
101 | \ |
102 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
103 | BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, TYPE>::type\ |
104 | PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ |
105 | { return FWD_FUNCTION(u); }\ |
106 | \ |
107 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
108 | BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_2<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, TYPE>::type\ |
109 | PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ |
110 | {\ |
111 | TYPE t((u));\ |
112 | return FWD_FUNCTION(::boost::move(t));\ |
113 | }\ |
114 | // |
115 | #endif |
116 | #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) |
117 | |
118 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
119 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
120 | { return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\ |
121 | \ |
122 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
123 | { return FWD_FUNCTION(::boost::move(x)); }\ |
124 | \ |
125 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
126 | BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c\ |
127 | < !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value\ |
128 | , RETURN_VALUE >::type\ |
129 | PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ |
130 | {\ |
131 | TYPE t((u));\ |
132 | return FWD_FUNCTION(::boost::move(t));\ |
133 | }\ |
134 | // |
135 | |
136 | #else //BOOST_NO_CXX11_RVALUE_REFERENCES |
137 | |
138 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ |
139 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
140 | { return FWD_FUNCTION(x); }\ |
141 | \ |
142 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
143 | { return FWD_FUNCTION(::boost::move(x)); }\ |
144 | // |
145 | |
146 | #endif //BOOST_NO_CXX11_RVALUE_REFERENCES |
147 | |
148 | //////////////////////////////////////// |
149 | // |
150 | // BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG |
151 | // |
152 | //////////////////////////////////////// |
153 | |
154 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES |
155 | |
156 | template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class UNLESS_CONVERTIBLE_TO, class TYPE> |
157 | struct boost_move_conversion_aware_catch_1arg_1 |
158 | : public ::boost::move_detail::enable_if_and |
159 | < RETURN_VALUE |
160 | , ::boost::move_detail::not_< ::boost::move_detail::is_same_or_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> > |
161 | , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> |
162 | , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM> |
163 | > |
164 | {}; |
165 | |
166 | template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class UNLESS_CONVERTIBLE_TO, class TYPE> |
167 | struct boost_move_conversion_aware_catch_1arg_2 |
168 | : public ::boost::move_detail::disable_if_or |
169 | < RETURN_VALUE |
170 | , ::boost::move_detail::is_same_or_convertible< BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> |
171 | , ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM> |
172 | , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> |
173 | > |
174 | {}; |
175 | |
176 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
177 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
178 | { return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\ |
179 | \ |
180 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
181 | { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ |
182 | \ |
183 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\ |
184 | { return FWD_FUNCTION(arg1, const_cast<const TYPE &>(x)); }\ |
185 | // |
186 | #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN) |
187 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
188 | BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
189 | \ |
190 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
191 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\ |
192 | typename boost_move_conversion_aware_catch_1arg_1<void, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type* = 0)\ |
193 | { return FWD_FUNCTION(arg1, u); }\ |
194 | \ |
195 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
196 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\ |
197 | typename boost_move_conversion_aware_catch_1arg_2<void, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type* = 0)\ |
198 | {\ |
199 | TYPE t((u));\ |
200 | return FWD_FUNCTION(arg1, ::boost::move(t));\ |
201 | }\ |
202 | // |
203 | #else |
204 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
205 | BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
206 | \ |
207 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
208 | BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_1<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type\ |
209 | PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ |
210 | { return FWD_FUNCTION(arg1, u); }\ |
211 | \ |
212 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
213 | BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_2<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type\ |
214 | PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ |
215 | {\ |
216 | TYPE t((u));\ |
217 | return FWD_FUNCTION(arg1, ::boost::move(t));\ |
218 | }\ |
219 | // |
220 | #endif |
221 | |
222 | #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) |
223 | |
224 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
225 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
226 | { return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\ |
227 | \ |
228 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
229 | { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ |
230 | \ |
231 | template<class BOOST_MOVE_TEMPL_PARAM>\ |
232 | BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::disable_if_or\ |
233 | < RETURN_VALUE \ |
234 | , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> \ |
235 | , ::boost::move_detail::is_same_or_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> \ |
236 | >::type\ |
237 | PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ |
238 | {\ |
239 | TYPE t((u));\ |
240 | return FWD_FUNCTION(arg1, ::boost::move(t));\ |
241 | }\ |
242 | // |
243 | |
244 | #else |
245 | |
246 | #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ |
247 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ |
248 | { return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\ |
249 | \ |
250 | BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ |
251 | { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ |
252 | // |
253 | |
254 | #endif |
255 | |
256 | #endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP |
257 | |