diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 87d63c6..2330a5c 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -23,9 +23,12 @@ #ifdef BOOST_MSVC #ifndef _CRT_SECURE_NO_DEPRECATE - #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #define _CRT_SECURE_NO_DEPRECATE - #define _SCL_SECURE_NO_WARNINGS + #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #endif + #ifndef _SCL_SECURE_NO_WARNINGS + #define BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #define _SCL_SECURE_NO_WARNINGS #endif #pragma warning (push) #pragma warning(disable:4996) @@ -1080,14 +1083,112 @@ struct has_trivial_destructor_after_move : BOOST_MOVE_BOOST_NS::has_trivial_destructor {}; + + +namespace move_detail { + +// Code from Jeffrey Lee Hellrung, many thanks + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T> struct forward_type { typedef T type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T> + struct forward_type + { typedef const T &type; }; + + template< class T> + struct forward_type< boost::rv > + { typedef T type; }; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + + + +// Code from Jeffrey Lee Hellrung, many thanks + +template< class T > struct is_rvalue_reference : BOOST_MOVE_BOOST_NS::integral_constant { }; +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct is_rvalue_reference< T&& > : BOOST_MOVE_BOOST_NS::integral_constant { }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct is_rvalue_reference< boost::rv& > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; + + template< class T > struct is_rvalue_reference< const boost::rv& > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct add_rvalue_reference { typedef T&& type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + namespace detail_add_rvalue_reference + { + template< class T + , bool emulation = ::boost::has_move_emulation_enabled::value + , bool rv = ::boost::move_detail::is_rv::value > + struct add_rvalue_reference_impl { typedef T type; }; + + template< class T, bool emulation> + struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; }; + + template< class T, bool rv > + struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv& type; }; + } // namespace detail_add_rvalue_reference + + template< class T > + struct add_rvalue_reference + : detail_add_rvalue_reference::add_rvalue_reference_impl + { }; + + template< class T > + struct add_rvalue_reference + { typedef T & type; }; + +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +template< class T > struct remove_rvalue_reference { typedef T type; }; + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< T&& > { typedef T type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +template +typename boost::move_detail::add_rvalue_reference::type declval(); + +} +// Ideas from Boost.Move review, Jeffrey Lee Hellrung: +// +//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? +// Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue +// references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than +// rv& (since T&& & -> T&). +// +//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? +// +//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated +// rvalue references in C++03. This may be necessary to prevent "accidental moves". + } //namespace boost { #if defined BOOST_MSVC #pragma warning (pop) #ifdef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #undef _CRT_SECURE_NO_DEPRECATE - #undef _SCL_SECURE_NO_WARNINGS + #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef _CRT_SECURE_NO_DEPRECATE + #endif + + #ifdef BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #undef BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #undef _SCL_SECURE_NO_WARNINGS #endif #endif