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