utility.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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
  12. #ifndef BOOST_MOVE_MOVE_UTILITY_HPP
  13. #define BOOST_MOVE_MOVE_UTILITY_HPP
  14. #include <boost/move/detail/config_begin.hpp>
  15. #include <boost/move/core.hpp>
  16. #include <boost/move/detail/meta_utils.hpp>
  17. #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  18. namespace boost {
  19. template<class T>
  20. struct enable_move_utility_emulation
  21. {
  22. static const bool value = true;
  23. };
  24. //////////////////////////////////////////////////////////////////////////////
  25. //
  26. // move()
  27. //
  28. //////////////////////////////////////////////////////////////////////////////
  29. template <class T>
  30. inline typename ::boost::move_detail::enable_if_c
  31. < enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value, T&>::type
  32. move(T& x) BOOST_NOEXCEPT
  33. {
  34. return x;
  35. }
  36. template <class T>
  37. inline typename ::boost::move_detail::enable_if_c
  38. < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
  39. move(T& x) BOOST_NOEXCEPT
  40. {
  41. return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
  42. }
  43. template <class T>
  44. inline typename ::boost::move_detail::enable_if_c
  45. < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
  46. move(rv<T>& x) BOOST_NOEXCEPT
  47. {
  48. return x;
  49. }
  50. //////////////////////////////////////////////////////////////////////////////
  51. //
  52. // forward()
  53. //
  54. //////////////////////////////////////////////////////////////////////////////
  55. template <class T>
  56. inline typename ::boost::move_detail::enable_if_c
  57. < enable_move_utility_emulation<T>::value && ::boost::move_detail::is_rv<T>::value, T &>::type
  58. forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
  59. {
  60. return const_cast<T&>(x);
  61. }
  62. template <class T>
  63. inline typename ::boost::move_detail::enable_if_c
  64. < enable_move_utility_emulation<T>::value && !::boost::move_detail::is_rv<T>::value, const T &>::type
  65. forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
  66. {
  67. return x;
  68. }
  69. } //namespace boost
  70. #else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  71. #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
  72. #include <utility>
  73. namespace boost{
  74. using ::std::move;
  75. using ::std::forward;
  76. } //namespace boost
  77. #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
  78. #include <boost/type_traits/remove_reference.hpp>
  79. namespace boost {
  80. //! This trait's internal boolean `value` is false in compilers with rvalue references
  81. //! and true in compilers without rvalue references.
  82. //!
  83. //! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
  84. //! so that the user can define a different move emulation for that type in namespace boost
  85. //! (e.g. another Boost library for its types) and avoid any overload ambiguity.
  86. template<class T>
  87. struct enable_move_utility_emulation
  88. {
  89. static const bool value = false;
  90. };
  91. //////////////////////////////////////////////////////////////////////////////
  92. //
  93. // move
  94. //
  95. //////////////////////////////////////////////////////////////////////////////
  96. #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
  97. //! This function provides a way to convert a reference into a rvalue reference
  98. //! in compilers with rvalue references. For other compilers converts T & into
  99. //! <i>::boost::rv<T> &</i> so that move emulation is activated.
  100. template <class T>
  101. rvalue_reference move(input_reference) noexcept;
  102. #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  103. //Old move approach, lvalues could bind to rvalue references
  104. template <class T>
  105. inline typename remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
  106. { return t; }
  107. #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
  108. template <class T>
  109. inline typename remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
  110. { return static_cast<typename remove_reference<T>::type &&>(t); }
  111. #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
  112. //////////////////////////////////////////////////////////////////////////////
  113. //
  114. // forward
  115. //
  116. //////////////////////////////////////////////////////////////////////////////
  117. #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
  118. //! This function provides limited form of forwarding that is usually enough for
  119. //! in-place construction and avoids the exponential overloading for
  120. //! achieve the limited forwarding in C++03.
  121. //!
  122. //! For compilers with rvalue references this function provides perfect forwarding.
  123. //!
  124. //! Otherwise:
  125. //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
  126. //! ::boost::rv<T> &
  127. //!
  128. //! * Else, output_reference is equal to input_reference.
  129. template <class T> output_reference forward(input_reference) noexcept;
  130. #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  131. //Old move approach, lvalues could bind to rvalue references
  132. template <class T>
  133. inline T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
  134. { return t; }
  135. #else //Old move
  136. //Implementation #5 from N2951, thanks to Howard Hinnant
  137. template <class T, class U>
  138. inline T&& forward(U&& t
  139. , typename ::boost::move_detail::enable_if_c<
  140. move_detail::is_lvalue_reference<T>::value ? move_detail::is_lvalue_reference<U>::value : true>::type * = 0/*
  141. , typename ::boost::move_detail::enable_if_c<
  142. move_detail::is_convertible
  143. <typename remove_reference<U>::type*, typename remove_reference<T>::type*>::value>::type * = 0*/) BOOST_NOEXCEPT
  144. { return static_cast<T&&>(t); }
  145. #endif //BOOST_MOVE_DOXYGEN_INVOKED
  146. } //namespace boost {
  147. #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
  148. #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
  149. #include <boost/move/detail/config_end.hpp>
  150. #endif //#ifndef BOOST_MOVE_MOVE_UTILITY_HPP