1 //////////////////////////////////////////////////////////////////////////////
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)
8 // See http://www.boost.org/libs/move for documentation.
10 //////////////////////////////////////////////////////////////////////////////
12 #ifndef BOOST_MOVE_MOVE_HELPERS_HPP
13 #define BOOST_MOVE_MOVE_HELPERS_HPP
15 #ifndef BOOST_CONFIG_HPP
16 # include <boost/config.hpp>
19 #if defined(BOOST_HAS_PRAGMA_ONCE)
23 #include <boost/move/core.hpp>
24 #include <boost/move/utility_core.hpp>
25 #include <boost/move/detail/type_traits.hpp>
27 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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)
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 &&
40 ////////////////////////////////////////
42 // BOOST_MOVE_CONVERSION_AWARE_CATCH
44 ////////////////////////////////////////
46 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
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
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>
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
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>
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)); }\
75 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
76 { return FWD_FUNCTION(::boost::move(x)); }\
78 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(TYPE &x)\
79 { return FWD_FUNCTION(const_cast<const TYPE &>(x)); }\
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)\
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); }\
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)\
95 return FWD_FUNCTION(::boost::move(t));\
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)\
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); }\
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)\
112 return FWD_FUNCTION(::boost::move(t));\
116 #elif (defined(_MSC_VER) && (_MSC_VER == 1600))
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)); }\
122 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
123 { return FWD_FUNCTION(::boost::move(x)); }\
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)\
132 return FWD_FUNCTION(::boost::move(t));\
136 #else //BOOST_NO_CXX11_RVALUE_REFERENCES
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); }\
142 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
143 { return FWD_FUNCTION(::boost::move(x)); }\
146 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
148 ////////////////////////////////////////
150 // BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
152 ////////////////////////////////////////
154 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
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
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>
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
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>
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)); }\
180 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
181 { return FWD_FUNCTION(arg1, ::boost::move(x)); }\
183 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\
184 { return FWD_FUNCTION(arg1, const_cast<const TYPE &>(x)); }\
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)\
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); }\
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)\
200 return FWD_FUNCTION(arg1, ::boost::move(t));\
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)\
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); }\
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)\
217 return FWD_FUNCTION(arg1, ::boost::move(t));\
222 #elif (defined(_MSC_VER) && (_MSC_VER == 1600))
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)); }\
228 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
229 { return FWD_FUNCTION(arg1, ::boost::move(x)); }\
231 template<class BOOST_MOVE_TEMPL_PARAM>\
232 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::disable_if_or\
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> \
237 PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
240 return FWD_FUNCTION(arg1, ::boost::move(t));\
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)); }\
250 BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
251 { return FWD_FUNCTION(arg1, ::boost::move(x)); }\
256 #endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP