move_helpers.hpp 12 KB

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