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