From 00db7a0829e49a9b1b264beb4cd247ea4dc3f944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 21 Oct 2021 16:11:15 +0200 Subject: [PATCH] Fixes #42 (" fails when BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE is set") --- doc/move.qbk | 1 + include/boost/move/utility_core.hpp | 75 +++++++++++++++-------------- test/unique_ptr_std_move.cpp | 30 ++++++++++++ 3 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 test/unique_ptr_std_move.cpp diff --git a/doc/move.qbk b/doc/move.qbk index bb551f0..ec67b0c 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -806,6 +806,7 @@ Special thanks to: * Fixed bugs: * [@https://github.com/boostorg/move/issues/40 Git Issue #40: ['"Warning 4675 is not defined in MSVC"]]. + * [@https://github.com/boostorg/move/issues/42 Git Issue #42: ['" fails when BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE is set"]]. [endsect] diff --git a/include/boost/move/utility_core.hpp b/include/boost/move/utility_core.hpp index 55042a9..edc1a73 100644 --- a/include/boost/move/utility_core.hpp +++ b/include/boost/move/utility_core.hpp @@ -258,44 +258,47 @@ #endif //BOOST_MOVE_DOXYGEN_INVOKED - ////////////////////////////////////////////////////////////////////////////// - // - // move_if_not_lvalue_reference - // - ////////////////////////////////////////////////////////////////////////////// - - - #if defined(BOOST_MOVE_DOXYGEN_INVOKED) - //! Effects: Calls `boost::move` if `input_reference` is not a lvalue reference. - //! Otherwise returns the reference - template output_reference move_if_not_lvalue_reference(input_reference) noexcept; - #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) - - //Old move approach, lvalues could bind to rvalue references - - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT - { return t; } - - #else //Old move - - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT - { return static_cast(t); } - - template - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(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 - } //namespace boost { - #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + #endif //BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE + + ////////////////////////////////////////////////////////////////////////////// + // + // move_if_not_lvalue_reference + // + ////////////////////////////////////////////////////////////////////////////// + + namespace boost { + + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! Effects: Calls `boost::move` if `input_reference` is not a lvalue reference. + //! Otherwise returns the reference + template output_reference move_if_not_lvalue_reference(input_reference) noexcept; + #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + + //Old move approach, lvalues could bind to rvalue references + + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT + { return t; } + + #else //Old move + + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT + { return static_cast(t); } + + template + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(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 + + } //namespace boost { #endif //BOOST_NO_CXX11_RVALUE_REFERENCES diff --git a/test/unique_ptr_std_move.cpp b/test/unique_ptr_std_move.cpp new file mode 100644 index 0000000..1985eb2 --- /dev/null +++ b/test/unique_ptr_std_move.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Howard Hinnant 2009 +// (C) Copyright Ion Gaztanaga 2014-2014. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE +#include +#include + +//////////////////////////////// +// main +//////////////////////////////// +int main() +{ + //Just test compilation errors + boost::movelib::unique_ptr a, b(boost::move(a)); + BOOST_TEST(!(b.get() || a.get())); + b = boost::move(a); + b.release(); + BOOST_TEST(!(b.get() || a.get())); + //Test results + return boost::report_errors(); +}