diff --git a/include/boost/move/detail/move_helpers.hpp b/include/boost/move/detail/move_helpers.hpp index ed6f3d5..49c5efe 100644 --- a/include/boost/move/detail/move_helpers.hpp +++ b/include/boost/move/detail/move_helpers.hpp @@ -13,28 +13,14 @@ #define BOOST_MOVE_MOVE_HELPERS_HPP #include -#include -#include -#include - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined(_MSC_VER) && (_MSC_VER == 1600)) -#include -#include -#include -#include -#endif -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#include -#endif - +#include #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -struct not_a_type; -struct not_a_type2; + #define BOOST_MOVE_CATCH_CONST(U) \ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type + typename ::boost::move_detail::if_< ::boost::move_detail::is_class_or_union, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type #define BOOST_MOVE_CATCH_RVALUE(U)\ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(U), not_a_type>::type + typename ::boost::move_detail::if_< ::boost::move_detail::is_class_or_union, BOOST_RV_REF(U), ::boost::move_detail::nat>::type #define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U) #else #define BOOST_MOVE_CATCH_CONST(U) const U & @@ -54,19 +40,19 @@ struct not_a_type2; { return FWD_FUNCTION(const_cast(x)); }\ \ template\ - typename ::boost::enable_if_c\ - < ::boost::is_class::value &&\ - ::boost::is_same::value &&\ + 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\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ { return FWD_FUNCTION(u); }\ \ template\ - typename ::boost::enable_if_c\ - < (!::boost::is_class::value || \ + typename ::boost::move_detail::enable_if_c\ + < (!::boost::move_detail::is_class_or_union::value || \ !::boost::move_detail::is_rv::value) && \ - !::boost::is_same::value \ + !::boost::move_detail::is_same::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -74,7 +60,7 @@ struct not_a_type2; return FWD_FUNCTION(::boost::move(t));\ }\ // -// ::boost::is_convertible::value && + #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ @@ -85,8 +71,8 @@ struct not_a_type2; { return FWD_FUNCTION(::boost::move(x)); }\ \ template\ - typename ::boost::enable_if_c\ - < !::boost::is_same::value\ + typename ::boost::move_detail::enable_if_c\ + < !::boost::move_detail::is_same::value\ , RETURN_VALUE >::type\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -121,18 +107,18 @@ struct not_a_type2; { return FWD_FUNCTION(arg1, const_cast(x)); }\ \ template\ - typename ::boost::enable_if_c<\ - ::boost::is_same::value &&\ + typename ::boost::move_detail::enable_if_c<\ + ::boost::move_detail::is_same::value &&\ !::boost::has_move_emulation_enabled::value\ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ { return FWD_FUNCTION(arg1, u); }\ \ template\ - typename ::boost::enable_if_c<\ + typename ::boost::move_detail::enable_if_c<\ !::boost::move_detail::is_rv::value && \ - !::boost::is_same::value && \ - !::boost::is_convertible::value \ + !::boost::move_detail::is_same::value && \ + !::boost::move_detail::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -151,9 +137,9 @@ struct not_a_type2; { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ \ template\ - typename ::boost::enable_if_c\ - < !::boost::is_same::value && \ - !::boost::is_convertible::value \ + typename ::boost::move_detail::enable_if_c\ + < !::boost::move_detail::is_same::value && \ + !::boost::move_detail::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp index 9412ddb..13a1adc 100644 --- a/test/conversion_test.cpp +++ b/test/conversion_test.cpp @@ -8,11 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// -#include #include - -#include -#include +#include #include #include #include @@ -113,16 +110,18 @@ class container BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - template + template iterator insert(Iterator, Iterator){ return iterator(); } ConstructionType construction_type() const - { return construction_type_impl(typename ::boost::is_class::type()); } + { return construction_type_impl + (typename ::boost::move_detail::integral_constant::value>()); + } - ConstructionType construction_type_impl(::boost::true_type) const + ConstructionType construction_type_impl(::boost::move_detail::true_type) const { return storage_->construction_type(); } - ConstructionType construction_type_impl(::boost::false_type) const + ConstructionType construction_type_impl(::boost::move_detail::false_type) const { return Copied; } iterator begin() const { return iterator(); } @@ -413,388 +412,3 @@ int main() return 0; } - -#include - -/* -#include -#include -#include -#include -#include -#include -#include - - -enum ConstructionType { Default, Copied, Moved, Other }; - -class conversion_source -{ - public: - conversion_source(){} - operator int() const { return 0; } -}; - -class conversion_target -{ - ConstructionType c_type_; - public: - conversion_target(conversion_source) - { c_type_ = Other; } - conversion_target() - { c_type_ = Default; } - conversion_target(const conversion_target &) - { c_type_ = Copied; } - ConstructionType construction_type() const - { return c_type_; } -}; - - -class conversion_target_copymovable -{ - ConstructionType c_type_; - BOOST_COPYABLE_AND_MOVABLE(conversion_target_copymovable) - public: - conversion_target_copymovable() - { c_type_ = Default; } - conversion_target_copymovable(conversion_source) - { c_type_ = Other; } - conversion_target_copymovable(const conversion_target_copymovable &) - { c_type_ = Copied; } - conversion_target_copymovable(BOOST_RV_REF(conversion_target_copymovable) ) - { c_type_ = Moved; } - conversion_target_copymovable &operator=(BOOST_RV_REF(conversion_target_copymovable) ) - { c_type_ = Moved; return *this; } - conversion_target_copymovable &operator=(BOOST_COPY_ASSIGN_REF(conversion_target_copymovable) ) - { c_type_ = Copied; return *this; } - ConstructionType construction_type() const - { return c_type_; } -}; - -class conversion_target_movable -{ - ConstructionType c_type_; - BOOST_MOVABLE_BUT_NOT_COPYABLE(conversion_target_movable) - public: - conversion_target_movable() - { c_type_ = Default; } - conversion_target_movable(conversion_source) - { c_type_ = Other; } - conversion_target_movable(BOOST_RV_REF(conversion_target_movable) ) - { c_type_ = Moved; } - conversion_target_movable &operator=(BOOST_RV_REF(conversion_target_movable) ) - { c_type_ = Moved; return *this; } - ConstructionType construction_type() const - { return c_type_; } -}; - -struct not_a_type; - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#define BOOST_MOVE_CATCH_CONST(U) \ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type -#define BOOST_MOVE_CATCH_RVALUE(U)\ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(T), not_a_type>::type -#else -#define BOOST_MOVE_CATCH_CONST(U) BOOST_CATCH_CONST_RLVALUE(U) -#define BOOST_MOVE_CATCH_RVALUE(U) BOOST_RV_REF(U) -#endif - -// BEGIN JLH additional definitions... - -template< class T > struct remove_const_remove_reference { typedef T type; }; -template< class T > struct remove_const_remove_reference< const T > : remove_const_remove_reference { }; -template< class T > struct remove_const_remove_reference< volatile T > : remove_const_remove_reference { }; -template< class T > struct remove_const_remove_reference< const volatile T > : remove_const_remove_reference { }; -template< class T > struct remove_const_remove_reference< T& > : remove_const_remove_reference { }; -template< class T > struct remove_const_remove_reference< boost::rv > : remove_const_remove_reference { }; - -template< class T > struct add_reference_add_const { typedef T const & type; }; -template< class T > struct add_reference_add_const< T& > { typedef T& type; }; - -template< class T, class U > -struct is_same_sans_const_sans_reference - : boost::is_same< - typename remove_const_remove_reference::type, - typename remove_const_remove_reference::type - > -{ }; - -template< class T > struct add_lvalue_reference { typedef T& type; }; -template<> struct add_lvalue_reference< void > { typedef void type; }; -template<> struct add_lvalue_reference< const void > { typedef const void type; }; -template<> struct add_lvalue_reference< volatile void > { typedef volatile void type; }; -template<> struct add_lvalue_reference< const volatile void > { typedef const volatile void type; }; -template< class T > struct add_lvalue_reference< T& > { typedef T& type; }; -template< class T > struct add_lvalue_reference< boost::rv > { typedef T& type; }; -template< class T > struct add_lvalue_reference< const boost::rv > { typedef const T& type; }; -template< class T > struct add_lvalue_reference< volatile boost::rv > { typedef volatile T& type; }; -template< class T > struct add_lvalue_reference< const volatile boost::rv > { typedef const volatile T& type; }; -template< class T > struct add_lvalue_reference< boost::rv& > { typedef T& type; }; -template< class T > struct add_lvalue_reference< const boost::rv& > { typedef const T& type; }; -template< class T > struct add_lvalue_reference< volatile boost::rv& > { typedef volatile T& type; }; -template< class T > struct add_lvalue_reference< const volatile boost::rv& > { typedef const volatile T& type; }; - -template< class T > struct remove_rvalue_reference { typedef T type; }; -template< class T > struct remove_rvalue_reference< boost::rv > { typedef T type; }; -template< class T > struct remove_rvalue_reference< const boost::rv > { typedef T type; }; -template< class T > struct remove_rvalue_reference< volatile boost::rv > { typedef T type; }; -template< class T > struct remove_rvalue_reference< const volatile boost::rv > { typedef T type; }; -template< class T > struct remove_rvalue_reference< boost::rv& > { typedef T type; }; -template< class T > struct remove_rvalue_reference< const boost::rv& > { typedef T type; }; -template< class T > struct remove_rvalue_reference< volatile boost::rv& > { typedef T type; }; -template< class T > struct remove_rvalue_reference< const volatile boost::rv& > { typedef T type; }; - -template< class T > -struct add_rvalue_reference - : boost::mpl::if_< - boost::has_move_emulation_enabled, - boost::rv&, - T - > -{ }; - -template< class T > -struct remove_crv - : remove_rvalue_reference -{ }; -template< class T > -struct remove_crv< const T > - : remove_rvalue_reference -{ }; - -template< class T > -inline typename add_lvalue_reference::type -as_lvalue(T& x) -{ return x; } - -// END JLH additional definitions... - -template -class container -{ - typename ::boost::aligned_storage::value>::type storage_; - public: - - ConstructionType construction_type() const - { return construction_type_impl(typename ::boost::is_class::type()); } - ConstructionType construction_type_impl(::boost::true_type) const - { return reinterpret_cast(storage_).construction_type(); } - ConstructionType construction_type_impl(::boost::false_type) const - { return Copied; } - -#if 0 - - // Ion's original implementation - - void push_back(BOOST_MOVE_CATCH_CONST(T) x) - { return priv_push_back(static_cast(x)); } - - void push_back(BOOST_MOVE_CATCH_RVALUE(T) x) - { return priv_push_back(::boost::move(x)); } - - //Tricks for C++03 - #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - void push_back(T &x) - { priv_push_back(const_cast(x)); } - - template - typename ::boost::enable_if_c - < ::boost::is_class::value && - ::boost::is_same::value && - !::boost::has_move_emulation_enabled::value - >::type - push_back(const U &u) - { return priv_push_back(u); } - - template - typename ::boost::enable_if_c - < ::boost::is_class::value && - !::boost::is_same::value && - !::boost::move_detail::is_rv::value - >::type - push_back(const U &u) - { - T t(u); - priv_push_back(::boost::move(t)); - } - - #endif - - private: - template - void priv_push_back(BOOST_FWD_REF(U) x) - { new (&storage_) T(::boost::forward(x)); } - -#else // #if 0|1 - - // JLH's current implementation (roughly; only showing C++03 here) - - template< class U > - typename boost::disable_if< - is_same_sans_const_sans_reference - >::type - push_back(const U& x) { priv_push_back(as_lvalue(x)); } - template< class U > - void - push_back(U& x) { priv_push_back(x); } - - typedef typename add_reference_add_const< - typename add_rvalue_reference::type - >::type rv_param_type; - - void - push_back(rv_param_type x) { priv_push_back(x); } -private: - template< class U > - void - priv_push_back(U& x) { new (&storage_) T(x); } - -#endif // #if 0|1 -}; - - -int main() -{ - conversion_target_movable a; - conversion_target_movable b(::boost::move(a)); - { - container c; - { - conversion_target x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - const conversion_target x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - c.push_back(conversion_target()); - assert(c.construction_type() == Copied); - } - { - conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Copied); - assert(c.construction_type() == Other); - } - { - const conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Copied); - assert(c.construction_type() == Other); - } - { - c.push_back(conversion_source()); - //assert(c.construction_type() == Copied); - assert(c.construction_type() == Other); - } - } - - { - container c; - { - conversion_target_copymovable x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - const conversion_target_copymovable x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - c.push_back(conversion_target_copymovable()); - assert(c.construction_type() == Moved); - } - { - conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - { - const conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - { - c.push_back(conversion_source()); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - } - { - container c; - //This should not compile - //{ - // conversion_target_movable x; - // c.push_back(x); - // assert(c.construction_type() == Copied); - //} - //{ - // const conversion_target_movable x; - // c.push_back(x); - // assert(c.construction_type() == Copied); - //} - { - c.push_back(conversion_target_movable()); - assert(c.construction_type() == Moved); - } - { - conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - { - const conversion_source x; - c.push_back(x); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - { - c.push_back(conversion_source()); - //assert(c.construction_type() == Moved); - assert(c.construction_type() == Other); - } - } - { - container c; - { - int x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - const int x = 0; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - c.push_back(int(0)); - assert(c.construction_type() == Copied); - } - { - conversion_source x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - - { - const conversion_source x; - c.push_back(x); - assert(c.construction_type() == Copied); - } - { - c.push_back(conversion_source()); - assert(c.construction_type() == Copied); - } - } - - return 0; -} -*/