traits.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2009-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_TRAITS_HPP
  13. #define BOOST_MOVE_MOVE_TRAITS_HPP
  14. #include <boost/move/detail/config_begin.hpp>
  15. #include <boost/type_traits/has_trivial_destructor.hpp>
  16. #include <boost/type_traits/is_nothrow_move_constructible.hpp>
  17. #include <boost/type_traits/is_nothrow_move_assignable.hpp>
  18. #include <boost/move/detail/meta_utils.hpp>
  19. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  20. #include <boost/move/core.hpp>
  21. #endif
  22. namespace boost {
  23. //! If this trait yields to true
  24. //! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
  25. //! means that if T is used as argument of a move construction/assignment,
  26. //! there is no need to call T's destructor.
  27. //! This optimization tipically is used to improve containers' performance.
  28. //!
  29. //! By default this trait is true if the type has trivial destructor,
  30. //! every class should specialize this trait if it wants to improve performance
  31. //! when inserted in containers.
  32. template <class T>
  33. struct has_trivial_destructor_after_move
  34. : ::boost::has_trivial_destructor<T>
  35. {};
  36. //! By default this traits returns
  37. //! <pre>boost::is_nothrow_move_constructible<T>::value && boost::is_nothrow_move_assignable<T>::value </pre>.
  38. //! Classes with non-throwing move constructor
  39. //! and assignment can specialize this trait to obtain some performance improvements.
  40. template <class T>
  41. struct has_nothrow_move
  42. : public ::boost::move_detail::integral_constant
  43. < bool
  44. , boost::is_nothrow_move_constructible<T>::value &&
  45. boost::is_nothrow_move_assignable<T>::value
  46. >
  47. {};
  48. namespace move_detail {
  49. // Code from Jeffrey Lee Hellrung, many thanks
  50. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  51. template< class T> struct forward_type { typedef T type; };
  52. #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  53. template< class T>
  54. struct forward_type
  55. { typedef const T &type; };
  56. template< class T>
  57. struct forward_type< boost::rv<T> >
  58. { typedef T type; };
  59. #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  60. template< class T > struct is_rvalue_reference : ::boost::move_detail::integral_constant<bool, false> { };
  61. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  62. template< class T > struct is_rvalue_reference< T&& > : ::boost::move_detail::integral_constant<bool, true> { };
  63. #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  64. template< class T > struct is_rvalue_reference< boost::rv<T>& >
  65. : ::boost::move_detail::integral_constant<bool, true>
  66. {};
  67. template< class T > struct is_rvalue_reference< const boost::rv<T>& >
  68. : ::boost::move_detail::integral_constant<bool, true>
  69. {};
  70. #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  71. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  72. template< class T > struct add_rvalue_reference { typedef T&& type; };
  73. #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  74. namespace detail_add_rvalue_reference
  75. {
  76. template< class T
  77. , bool emulation = ::boost::has_move_emulation_enabled<T>::value
  78. , bool rv = ::boost::move_detail::is_rv<T>::value >
  79. struct add_rvalue_reference_impl { typedef T type; };
  80. template< class T, bool emulation>
  81. struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
  82. template< class T, bool rv >
  83. struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
  84. } // namespace detail_add_rvalue_reference
  85. template< class T >
  86. struct add_rvalue_reference
  87. : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
  88. { };
  89. template< class T >
  90. struct add_rvalue_reference<T &>
  91. { typedef T & type; };
  92. #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  93. template< class T > struct remove_rvalue_reference { typedef T type; };
  94. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  95. template< class T > struct remove_rvalue_reference< T&& > { typedef T type; };
  96. #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  97. template< class T > struct remove_rvalue_reference< rv<T> > { typedef T type; };
  98. template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; };
  99. template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; };
  100. template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
  101. template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; };
  102. template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; };
  103. template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; };
  104. template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
  105. #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  106. template <typename T>
  107. typename boost::move_detail::add_rvalue_reference<T>::type declval();
  108. } //move_detail {
  109. // Ideas from Boost.Move review, Jeffrey Lee Hellrung:
  110. //
  111. //- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
  112. // Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
  113. // references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
  114. // rv<T>& (since T&& & -> T&).
  115. //
  116. //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
  117. //
  118. //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
  119. // rvalue references in C++03. This may be necessary to prevent "accidental moves".
  120. } //namespace boost {
  121. #include <boost/move/detail/config_end.hpp>
  122. #endif //#ifndef BOOST_MOVE_MOVE_TRAITS_HPP