diff --git a/doc/move.qbk b/doc/move.qbk index b0ff171..c32c0fe 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -638,7 +638,7 @@ will get the non-const copy constructor overload, which will surely surprise use } This limitation forces the user to define a const version of the copy assignment, -in all classes holding copyable and movable classes which might annoying in some cases. +in all classes holding copyable and movable classes which might be annoying in some cases. An alternative is to implement a single `operator =()` for copyable and movable classes [@http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ using "pass by value" semantics]: @@ -755,6 +755,12 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[section:release_notes_boost_1_57_00 Boost 1.57 Release] + +* Fixed bug [@https://svn.boost.org/trac/boost/ticket/9785 Trac #9785: ['"Compiler warning with intel icc in boost/move/core.hpp"]], + +[endsect] + [section:release_notes_boost_1_56_00 Boost 1.56 Release] * Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET]. diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index 0efa2af..de034e6 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -45,7 +45,11 @@ #include //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers - #if defined(__GNUC__) && (__GNUC__ >= 4) + #if defined(__GNUC__) && (__GNUC__ >= 4) && \ + (\ + defined(BOOST_GCC) || \ + (defined(BOOST_INTEL) && (BOOST_INTEL_CXX_VERSION >= 1300)) \ + ) #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) #else #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS diff --git a/include/boost/move/detail/meta_utils.hpp b/include/boost/move/detail/meta_utils.hpp index 0da3c68..c95d7cf 100644 --- a/include/boost/move/detail/meta_utils.hpp +++ b/include/boost/move/detail/meta_utils.hpp @@ -120,6 +120,29 @@ struct is_lvalue_reference : public integral_constant {}; +//remove_reference +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct remove_reference +{ + typedef T type; +}; + +#endif + template struct is_class_or_union { diff --git a/include/boost/move/utility.hpp b/include/boost/move/utility.hpp index 964500e..d4219a1 100644 --- a/include/boost/move/utility.hpp +++ b/include/boost/move/utility.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) @@ -96,8 +97,6 @@ #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE - #include - namespace boost { //! This trait's internal boolean `value` is false in compilers with rvalue references @@ -129,14 +128,14 @@ //Old move approach, lvalues could bind to rvalue references template - inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT + inline typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return t; } #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES template - inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT - { return static_cast::type &&>(t); } + inline typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT + { return static_cast::type &&>(t); } #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES @@ -170,16 +169,17 @@ #else //Old move - //Implementation #5 from N2951, thanks to Howard Hinnant + template + inline T&& forward(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT + { return static_cast(t); } - template - inline T&& forward(U&& t - , typename ::boost::move_detail::enable_if_c< - move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* - , typename ::boost::move_detail::enable_if_c< - move_detail::is_convertible - ::type*, typename remove_reference::type*>::value>::type * = 0*/) BOOST_NOEXCEPT - { return static_cast(t); } + template + inline T&& forward(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT + { + //"boost::forward error: 'T' is a lvalue reference, can't forward as rvalue."; + BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value); + return static_cast(t); + } #endif //BOOST_MOVE_DOXYGEN_INVOKED diff --git a/test/move.cpp b/test/move.cpp index 5ae0854..a01c230 100644 --- a/test/move.cpp +++ b/test/move.cpp @@ -110,40 +110,40 @@ int main() movable m3(function(movable(boost::move(m2)))); movable m4(function(boost::move(m3))); (void)m;(void)m2;(void)m3;(void)m4; - } + } { movable m; movable m2(boost::move(m)); movable m3(functionr(movable(boost::move(m2)))); movable m4(functionr(boost::move(m3))); (void)m;(void)m2;(void)m3;(void)m4; - } + } { movable m; movable m2(boost::move(m)); movable m3(function2(movable(boost::move(m2)))); movable m4(function2(boost::move(m3))); (void)m;(void)m2;(void)m3;(void)m4; - } + } { movable m; movable m2(boost::move(m)); movable m3(function2r(movable(boost::move(m2)))); movable m4(function2r(boost::move(m3))); (void)m;(void)m2;(void)m3;(void)m4; - } + } { movable m; movable m2(boost::move(m)); movable m3(move_return_function()); (void)m;(void)m2;(void)m3; - } + } { movable m; movable m2(boost::move(m)); movable m3(move_return_function2()); (void)m;(void)m2;(void)m3; - } + } { //movable movable m (factory_wrapper(factory()));