core.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2012-2012.
  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. //! \file core.hpp
  12. //! This header implements macros to define movable classes and
  13. //! move-aware functions
  14. #ifndef BOOST_MOVE_CORE_HPP
  15. #define BOOST_MOVE_CORE_HPP
  16. #include <boost/move/detail/config_begin.hpp>
  17. //boost_move_no_copy_constructor_or_assign typedef
  18. //used to detect noncopyable types for other Boost libraries.
  19. #ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
  20. #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
  21. private:\
  22. TYPE(TYPE &);\
  23. TYPE& operator=(TYPE &);\
  24. public:\
  25. typedef int boost_move_no_copy_constructor_or_assign; \
  26. private:\
  27. //
  28. #else
  29. #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
  30. public:\
  31. TYPE(TYPE const &) = delete;\
  32. TYPE& operator=(TYPE const &) = delete;\
  33. public:\
  34. typedef int boost_move_no_copy_constructor_or_assign; \
  35. private:\
  36. //
  37. #endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
  38. #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  39. #include <boost/move/detail/meta_utils.hpp>
  40. //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
  41. #if defined(__GNUC__) && (__GNUC__ >= 4)
  42. #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
  43. #else
  44. #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
  45. #endif
  46. namespace boost {
  47. //////////////////////////////////////////////////////////////////////////////
  48. //
  49. // struct rv
  50. //
  51. //////////////////////////////////////////////////////////////////////////////
  52. template <class T>
  53. class rv
  54. : public ::boost::move_detail::if_c
  55. < ::boost::move_detail::is_class_or_union<T>::value
  56. , T
  57. , ::boost::move_detail::empty
  58. >::type
  59. {
  60. rv();
  61. ~rv();
  62. rv(rv const&);
  63. void operator=(rv const&);
  64. } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
  65. //////////////////////////////////////////////////////////////////////////////
  66. //
  67. // move_detail::is_rv
  68. //
  69. //////////////////////////////////////////////////////////////////////////////
  70. namespace move_detail {
  71. template <class T>
  72. struct is_rv
  73. : ::boost::move_detail::integral_constant<bool, false>
  74. {};
  75. template <class T>
  76. struct is_rv< rv<T> >
  77. : ::boost::move_detail::integral_constant<bool, true>
  78. {};
  79. template <class T>
  80. struct is_rv< const rv<T> >
  81. : ::boost::move_detail::integral_constant<bool, true>
  82. {};
  83. } //namespace move_detail {
  84. //////////////////////////////////////////////////////////////////////////////
  85. //
  86. // has_move_emulation_enabled
  87. //
  88. //////////////////////////////////////////////////////////////////////////////
  89. template<class T>
  90. struct has_move_emulation_enabled
  91. : ::boost::move_detail::is_convertible< T, ::boost::rv<T>& >
  92. {};
  93. template<class T>
  94. struct has_move_emulation_enabled<T&>
  95. : ::boost::move_detail::integral_constant<bool, false>
  96. {};
  97. template<class T>
  98. struct has_move_emulation_enabled< ::boost::rv<T> >
  99. : ::boost::move_detail::integral_constant<bool, false>
  100. {};
  101. } //namespace boost {
  102. #define BOOST_RV_REF(TYPE)\
  103. ::boost::rv< TYPE >& \
  104. //
  105. #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  106. ::boost::rv< TYPE<ARG1, ARG2> >& \
  107. //
  108. #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  109. ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
  110. //
  111. #define BOOST_RV_REF_BEG\
  112. ::boost::rv< \
  113. //
  114. #define BOOST_RV_REF_END\
  115. >& \
  116. //
  117. #define BOOST_FWD_REF(TYPE)\
  118. const TYPE & \
  119. //
  120. #define BOOST_COPY_ASSIGN_REF(TYPE)\
  121. const ::boost::rv< TYPE >& \
  122. //
  123. #define BOOST_COPY_ASSIGN_REF_BEG \
  124. const ::boost::rv< \
  125. //
  126. #define BOOST_COPY_ASSIGN_REF_END \
  127. >& \
  128. //
  129. #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  130. const ::boost::rv< TYPE<ARG1, ARG2> >& \
  131. //
  132. #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  133. const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
  134. //
  135. #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
  136. const ::boost::rv< TYPE >& \
  137. //
  138. //////////////////////////////////////////////////////////////////////////////
  139. //
  140. // BOOST_MOVABLE_BUT_NOT_COPYABLE
  141. //
  142. //////////////////////////////////////////////////////////////////////////////
  143. #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
  144. BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
  145. public:\
  146. operator ::boost::rv<TYPE>&() \
  147. { return *static_cast< ::boost::rv<TYPE>* >(this); }\
  148. operator const ::boost::rv<TYPE>&() const \
  149. { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
  150. private:\
  151. //
  152. //////////////////////////////////////////////////////////////////////////////
  153. //
  154. // BOOST_COPYABLE_AND_MOVABLE
  155. //
  156. //////////////////////////////////////////////////////////////////////////////
  157. #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
  158. public:\
  159. TYPE& operator=(TYPE &t)\
  160. { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
  161. public:\
  162. operator ::boost::rv<TYPE>&() \
  163. { return *static_cast< ::boost::rv<TYPE>* >(this); }\
  164. operator const ::boost::rv<TYPE>&() const \
  165. { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
  166. private:\
  167. //
  168. #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
  169. public:\
  170. operator ::boost::rv<TYPE>&() \
  171. { return *static_cast< ::boost::rv<TYPE>* >(this); }\
  172. operator const ::boost::rv<TYPE>&() const \
  173. { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
  174. private:\
  175. //
  176. #else //BOOST_NO_CXX11_RVALUE_REFERENCES
  177. //Compiler workaround detection
  178. #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  179. #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
  180. //Pre-standard rvalue binding rules
  181. #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
  182. #elif defined(_MSC_VER) && (_MSC_VER == 1600)
  183. //Standard rvalue binding rules but with some bugs
  184. #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
  185. //Use standard library for MSVC to avoid namespace issues as
  186. //some move calls in the STL are not fully qualified.
  187. //#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
  188. #endif
  189. #endif
  190. //! This macro marks a type as movable but not copyable, disabling copy construction
  191. //! and assignment. The user will need to write a move constructor/assignment as explained
  192. //! in the documentation to fully write a movable but not copyable class.
  193. #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
  194. BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
  195. public:\
  196. typedef int boost_move_emulation_t;\
  197. //
  198. //! This macro marks a type as copyable and movable.
  199. //! The user will need to write a move constructor/assignment and a copy assignment
  200. //! as explained in the documentation to fully write a copyable and movable class.
  201. #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
  202. //
  203. #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  204. #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
  205. //
  206. #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  207. namespace boost {
  208. //!This trait yields to a compile-time true boolean if T was marked as
  209. //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
  210. //!rvalue references are not available on the platform. False otherwise.
  211. template<class T>
  212. struct has_move_emulation_enabled
  213. {
  214. static const bool value = false;
  215. };
  216. } //namespace boost{
  217. //!This macro is used to achieve portable syntax in move
  218. //!constructors and assignments for classes marked as
  219. //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
  220. #define BOOST_RV_REF(TYPE)\
  221. TYPE && \
  222. //
  223. //!This macro is used to achieve portable syntax in move
  224. //!constructors and assignments for template classes marked as
  225. //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
  226. //!As macros have problems with comma-separatd template arguments,
  227. //!the template argument must be preceded with BOOST_RV_REF_START
  228. //!and ended with BOOST_RV_REF_END
  229. #define BOOST_RV_REF_BEG\
  230. \
  231. //
  232. //!This macro is used to achieve portable syntax in move
  233. //!constructors and assignments for template classes marked as
  234. //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
  235. //!As macros have problems with comma-separatd template arguments,
  236. //!the template argument must be preceded with BOOST_RV_REF_START
  237. //!and ended with BOOST_RV_REF_END
  238. #define BOOST_RV_REF_END\
  239. && \
  240. //!This macro is used to achieve portable syntax in copy
  241. //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
  242. #define BOOST_COPY_ASSIGN_REF(TYPE)\
  243. const TYPE & \
  244. //
  245. //! This macro is used to implement portable perfect forwarding
  246. //! as explained in the documentation.
  247. #define BOOST_FWD_REF(TYPE)\
  248. TYPE && \
  249. //
  250. #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  251. /// @cond
  252. #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  253. TYPE<ARG1, ARG2> && \
  254. //
  255. #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  256. TYPE<ARG1, ARG2, ARG3> && \
  257. //
  258. #define BOOST_COPY_ASSIGN_REF_BEG \
  259. const \
  260. //
  261. #define BOOST_COPY_ASSIGN_REF_END \
  262. & \
  263. //
  264. #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  265. const TYPE<ARG1, ARG2> & \
  266. //
  267. #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  268. const TYPE<ARG1, ARG2, ARG3>& \
  269. //
  270. #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
  271. const TYPE & \
  272. //
  273. /// @endcond
  274. #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  275. #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
  276. #include <boost/move/detail/config_end.hpp>
  277. #endif //#ifndef BOOST_MOVE_CORE_HPP