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