diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index 408a713..8335982 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -53,6 +53,12 @@ #include + #if 1 + #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) static_cast(ARG) + #else + #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast(ARG) + #endif + //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers #if defined(__GNUC__) && (__GNUC__ >= 4) && \ (\ @@ -101,6 +107,12 @@ : integral_constant::value > {}; + template + struct is_not_rv + { + static const bool value = !is_rv::value; + }; + } //namespace move_detail { ////////////////////////////////////////////////////////////////////////////// @@ -113,6 +125,12 @@ : ::boost::move_detail::has_move_emulation_enabled_impl {}; + template + struct has_move_emulation_disabled + { + static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl::value; + }; + } //namespace boost { #define BOOST_RV_REF(TYPE)\ @@ -183,7 +201,7 @@ , ::boost::rv&>::type move_return(T& x) BOOST_NOEXCEPT { - return *static_cast< ::boost::rv* >(::boost::move_detail::addressof(x)); + return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, ::boost::move_detail::addressof(x)); } template @@ -216,9 +234,9 @@ BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\ public:\ operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ private:\ // @@ -231,21 +249,21 @@ #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ public:\ TYPE& operator=(TYPE &t)\ - { this->operator=(static_cast &>(const_cast(t))); return *this;}\ + { this->operator=(const_cast(t)); return *this;}\ public:\ operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ private:\ // #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ public:\ operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ private:\ // @@ -295,6 +313,12 @@ static const bool value = false; }; + template + struct has_move_emulation_disabled + { + static const bool value = true; + }; + } //namespace boost{ //!This macro is used to achieve portable syntax in move diff --git a/include/boost/move/detail/meta_utils.hpp b/include/boost/move/detail/meta_utils.hpp index 682c89c..9ba41b8 100644 --- a/include/boost/move/detail/meta_utils.hpp +++ b/include/boost/move/detail/meta_utils.hpp @@ -33,11 +33,53 @@ template class rv; namespace move_detail { +////////////////////////////////////// +// is_different +////////////////////////////////////// +template +struct is_different +{ + static const bool value = !is_same::value; +}; + +////////////////////////////////////// +// apply +////////////////////////////////////// +template +struct apply +{ + typedef typename F::template apply::type type; +}; + +////////////////////////////////////// +// bool_ +////////////////////////////////////// + +template< bool C_ > +struct bool_ : integral_constant +{ + operator bool() const { return C_; } + bool operator()() const { return C_; } +}; + +typedef bool_ true_; +typedef bool_ false_; + ////////////////////////////////////// // nat ////////////////////////////////////// struct nat{}; +////////////////////////////////////// +// yes_type/no_type +////////////////////////////////////// +typedef char yes_type; + +struct no_type +{ + char _[2]; +}; + ////////////////////////////////////// // natify ////////////////////////////////////// @@ -86,9 +128,27 @@ struct remove_reference< const rv &> typedef T type; }; - #endif +////////////////////////////////////// +// remove_pointer +////////////////////////////////////// + +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; + +////////////////////////////////////// +// add_pointer +////////////////////////////////////// +template< class T > +struct add_pointer +{ + typedef typename remove_reference::type* type; +}; + ////////////////////////////////////// // add_const ////////////////////////////////////// @@ -151,6 +211,19 @@ struct is_lvalue_reference static const bool value = true; }; + +////////////////////////////////////// +// identity +////////////////////////////////////// +template +struct identity +{ + typedef T type; + typedef typename add_const_lvalue_reference::type reference; + reference operator()(reference t) + { return t; } +}; + ////////////////////////////////////// // is_class_or_union ////////////////////////////////////// @@ -241,9 +314,128 @@ class is_convertible #endif +template< + bool C + , typename F1 + , typename F2 + > +struct eval_if_c + : if_c::type +{}; + +template< + typename C + , typename T1 + , typename T2 + > +struct eval_if + : if_::type +{}; + +template +struct enable_if_convertible + : enable_if< is_convertible, R> +{}; + +template +struct disable_if_convertible + : disable_if< is_convertible, R> +{}; + ////////////////////////////////////////////////////////////////////////////// // -// has_move_emulation_enabled_impl +// and_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct and_impl + : and_impl +{}; + +template<> +struct and_impl +{ + static const bool value = true; +}; + +template +struct and_impl +{ + static const bool value = false; +}; + +template +struct and_ + : and_impl +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// or_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct or_impl + : or_impl +{}; + +template<> +struct or_impl +{ + static const bool value = false; +}; + +template +struct or_impl +{ + static const bool value = true; +}; + +template +struct or_ + : or_impl +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// not_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct not_ +{ + static const bool value = !T::value; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// enable_if_and / disable_if_and / enable_if_or / disable_if_or +// +////////////////////////////////////////////////////////////////////////////// + +template +struct enable_if_and + : enable_if_c< and_::value, R> +{}; + +template +struct disable_if_and + : disable_if_c< and_::value, R> +{}; + +template +struct enable_if_or + : enable_if_c< or_::value, R> +{}; + +template +struct disable_if_or + : disable_if_c< or_::value, R> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// has_move_emulation_enabled_impl // ////////////////////////////////////////////////////////////////////////////// template diff --git a/include/boost/move/detail/meta_utils_core.hpp b/include/boost/move/detail/meta_utils_core.hpp index 283242b..4d715a0 100644 --- a/include/boost/move/detail/meta_utils_core.hpp +++ b/include/boost/move/detail/meta_utils_core.hpp @@ -49,16 +49,15 @@ template struct if_ : if_c<0 != T1::value, T2, T3> {}; -//enable_if_ +////////////////////////////////////// +// enable_if_c +////////////////////////////////////// template struct enable_if_c { typedef T type; }; -////////////////////////////////////// -// enable_if_c -////////////////////////////////////// template struct enable_if_c {}; @@ -68,6 +67,14 @@ struct enable_if_c {}; template struct enable_if : enable_if_c {}; +////////////////////////////////////// +// disable_if_c +////////////////////////////////////// +template +struct disable_if_c + : enable_if_c +{}; + ////////////////////////////////////// // disable_if ////////////////////////////////////// @@ -83,19 +90,14 @@ struct integral_constant static const T value = v; typedef T value_type; typedef integral_constant type; + + operator T() const { return value; } + T operator()() const { return value; } }; typedef integral_constant true_type; typedef integral_constant false_type; -////////////////////////////////////// -// identity -////////////////////////////////////// -template -struct identity -{ - typedef T type; -}; ////////////////////////////////////// // is_same diff --git a/include/boost/move/detail/move_helpers.hpp b/include/boost/move/detail/move_helpers.hpp index f4fd26c..e3b8883 100644 --- a/include/boost/move/detail/move_helpers.hpp +++ b/include/boost/move/detail/move_helpers.hpp @@ -48,20 +48,24 @@ { return FWD_FUNCTION(const_cast(x)); }\ \ template\ - typename ::boost::move_detail::enable_if_c\ - < ::boost::move_detail::is_class_or_union::value &&\ - ::boost::move_detail::is_same::value &&\ - !::boost::has_move_emulation_enabled::value\ - , RETURN_VALUE >::type\ + typename ::boost::move_detail::enable_if_and\ + < RETURN_VALUE \ + , ::boost::move_detail::is_same\ + , ::boost::move_detail::is_class_or_union\ + , ::boost::has_move_emulation_disabled\ + >::type\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ { return FWD_FUNCTION(u); }\ \ template\ - typename ::boost::move_detail::enable_if_c\ - < (!::boost::move_detail::is_class_or_union::value || \ - !::boost::move_detail::is_rv::value) && \ - !::boost::move_detail::is_same::value \ - , RETURN_VALUE >::type\ + typename ::boost::move_detail::disable_if_or\ + < RETURN_VALUE \ + , ::boost::move_detail::is_same \ + , ::boost::move_detail::and_ \ + < ::boost::move_detail::is_rv \ + , ::boost::move_detail::is_class_or_union \ + > \ + >::type\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ {\ TYPE t(u);\ @@ -115,19 +119,21 @@ { return FWD_FUNCTION(arg1, const_cast(x)); }\ \ template\ - typename ::boost::move_detail::enable_if_c<\ - ::boost::move_detail::is_same::value &&\ - !::boost::has_move_emulation_enabled::value\ - , RETURN_VALUE >::type\ + typename ::boost::move_detail::enable_if_and\ + < RETURN_VALUE \ + , ::boost::move_detail::is_same\ + , ::boost::has_move_emulation_disabled\ + >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ { return FWD_FUNCTION(arg1, u); }\ \ template\ - typename ::boost::move_detail::enable_if_c<\ - !::boost::move_detail::is_rv::value && \ - !::boost::move_detail::is_same::value && \ - !::boost::move_detail::is_convertible::value \ - , RETURN_VALUE >::type\ + typename ::boost::move_detail::disable_if_or\ + < RETURN_VALUE \ + , ::boost::move_detail::is_rv\ + , ::boost::move_detail::is_same\ + , ::boost::move_detail::is_convertible\ + >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ TYPE t(u);\ @@ -145,10 +151,11 @@ { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ \ template\ - typename ::boost::move_detail::enable_if_c\ - < !::boost::move_detail::is_same::value && \ - !::boost::move_detail::is_convertible::value \ - , RETURN_VALUE >::type\ + typename ::boost::move_detail::disable_if_or\ + < RETURN_VALUE \ + , ::boost::move_detail::is_same \ + , ::boost::move_detail::is_convertible \ + >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ TYPE t(u);\ diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index ac0bbcd..17cfa1f 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -341,23 +341,17 @@ struct is_pointer { static const bool value = true; }; ////////////////////////// -// add_reference +// unvoid_ref ////////////////////////// +template struct unvoid_ref : add_lvalue_reference{}; +template <> struct unvoid_ref { typedef unvoid_ref & type; }; +template <> struct unvoid_ref { typedef unvoid_ref & type; }; +template <> struct unvoid_ref { typedef unvoid_ref & type; }; +template <> struct unvoid_ref { typedef unvoid_ref & type; }; + template -struct add_reference -{ typedef T& type; }; - -template -struct add_reference -{ typedef T& type; }; - -template<> -struct add_reference -{ typedef nat &type; }; - -template<> -struct add_reference -{ typedef const nat &type; }; +struct add_reference : add_lvalue_reference +{}; ////////////////////////// // add_const_reference @@ -370,6 +364,14 @@ template struct add_const_reference { typedef T& type; }; +////////////////////////// +// add_const_if_c +////////////////////////// +template +struct add_const_if_c + : if_c::type, T> +{}; + ////////////////////////// // remove_const ////////////////////////// diff --git a/include/boost/move/utility_core.hpp b/include/boost/move/utility_core.hpp index 7b88bc1..89e4f07 100644 --- a/include/boost/move/utility_core.hpp +++ b/include/boost/move/utility_core.hpp @@ -47,24 +47,33 @@ ////////////////////////////////////////////////////////////////////////////// template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && !has_move_emulation_enabled::value, T&>::type + inline typename ::boost::move_detail::enable_if_and + < T & + , enable_move_utility_emulation + , has_move_emulation_disabled + >::type move(T& x) BOOST_NOEXCEPT { return x; } template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type + inline typename ::boost::move_detail::enable_if_and + < rv& + , enable_move_utility_emulation + , has_move_emulation_enabled + >::type move(T& x) BOOST_NOEXCEPT { - return *static_cast* >(::boost::move_detail::addressof(x)); + return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, ::boost::move_detail::addressof(x) ); } template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type + inline typename ::boost::move_detail::enable_if_and + < rv& + , enable_move_utility_emulation + , has_move_emulation_enabled + >::type move(rv& x) BOOST_NOEXCEPT { return x; @@ -77,17 +86,23 @@ ////////////////////////////////////////////////////////////////////////////// template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && ::boost::move_detail::is_rv::value, T &>::type + inline typename ::boost::move_detail::enable_if_and + < T & + , enable_move_utility_emulation + , ::boost::move_detail::is_rv + >::type forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return const_cast(x); } template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && !::boost::move_detail::is_rv::value, const T &>::type - forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT + inline typename ::boost::move_detail::enable_if_and + < const T & + , enable_move_utility_emulation + , ::boost::move_detail::is_not_rv + >::type + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return x; } @@ -99,22 +114,25 @@ ////////////////////////////////////////////////////////////////////////////// template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && - ::boost::move_detail::is_rv::value - , T &>::type + inline typename ::boost::move_detail::enable_if_and + < T & + , enable_move_utility_emulation + , ::boost::move_detail::is_rv + >::type move_if_not_lvalue_reference(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return const_cast(x); } template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && - !::boost::move_detail::is_rv::value && - (::boost::move_detail::is_lvalue_reference::value || - !has_move_emulation_enabled::value) - , typename ::boost::move_detail::add_lvalue_reference::type + inline typename ::boost::move_detail::enable_if_and + < typename ::boost::move_detail::add_lvalue_reference::type + , enable_move_utility_emulation + , ::boost::move_detail::is_not_rv + , ::boost::move_detail::or_ + < ::boost::move_detail::is_lvalue_reference + , has_move_emulation_disabled + > >::type move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type &x) BOOST_NOEXCEPT { @@ -122,12 +140,14 @@ } template - inline typename ::boost::move_detail::enable_if_c - < enable_move_utility_emulation::value && - !::boost::move_detail::is_rv::value && - (!::boost::move_detail::is_lvalue_reference::value && - has_move_emulation_enabled::value) - , rv& + inline typename ::boost::move_detail::enable_if_and + < rv& + , enable_move_utility_emulation + , ::boost::move_detail::is_not_rv + , ::boost::move_detail::and_ + < ::boost::move_detail::not_< ::boost::move_detail::is_lvalue_reference > + , has_move_emulation_enabled + > >::type move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type &x) BOOST_NOEXCEPT { diff --git a/test/unique_ptr_modifiers.cpp b/test/unique_ptr_modifiers.cpp index 3de952d..376c104 100644 --- a/test/unique_ptr_modifiers.cpp +++ b/test/unique_ptr_modifiers.cpp @@ -49,6 +49,7 @@ void test() int* j = p.release(); BOOST_TEST(p.get() == 0); BOOST_TEST(i == j); + p.reset(j); } //Unbounded array unique_ptr { @@ -57,6 +58,7 @@ void test() int* j = p.release(); BOOST_TEST(p.get() == 0); BOOST_TEST(i == j); + p.reset(j); } //Bounded array unique_ptr { @@ -65,6 +67,7 @@ void test() int* j = p.release(); BOOST_TEST(p.get() == 0); BOOST_TEST(i == j); + p.reset(j); } }