diff --git a/include/boost/core/exchange.hpp b/include/boost/core/exchange.hpp index 5c6469c..bc8a9fc 100644 --- a/include/boost/core/exchange.hpp +++ b/include/boost/core/exchange.hpp @@ -15,18 +15,10 @@ Distributed under the Boost Software License, Version 1.0. #endif namespace boost { -namespace detail { - -template -struct exchange_type { - typedef T type; -}; - -} /* detail */ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -template -inline T exchange(T& t, const typename detail::exchange_type::type& u) +template +inline T exchange(T& t, const U& u) { T v = t; t = u; @@ -34,19 +26,11 @@ inline T exchange(T& t, const typename detail::exchange_type::type& u) } #else #if BOOST_WORKAROUND(BOOST_MSVC, < 1800) -template -inline T exchange(T& t, const typename detail::exchange_type::type& u) +template +inline T exchange(T& t, U&& u) { T v = std::move(t); - t = u; - return v; -} - -template -inline T exchange(T& t, typename detail::exchange_type::type&& u) -{ - T v = std::move(t); - t = std::move(u); + t = std::forward(u); return v; } #else diff --git a/test/exchange_move_test.cpp b/test/exchange_move_test.cpp index 57255b8..0ce20af 100644 --- a/test/exchange_move_test.cpp +++ b/test/exchange_move_test.cpp @@ -59,10 +59,37 @@ void test2() BOOST_TEST(x.i() == 2); } +class C3 { +public: + explicit C3(int i) + : i_(i) { } + C3(C3&& c) + : i_(c.i_) { } + C3& operator=(C1&& c) { + i_ = c.i(); + return *this; + } + int i() const { + return i_; + } +private: + C3(const C3&); + C3& operator=(const C3&); + int i_; +}; + +void test3() +{ + C3 x(1); + BOOST_TEST(boost::exchange(x, C1(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + int main() { test1(); test2(); + test3(); return boost::report_errors(); } #else diff --git a/test/exchange_test.cpp b/test/exchange_test.cpp index a370d11..b6ddfa6 100644 --- a/test/exchange_test.cpp +++ b/test/exchange_test.cpp @@ -56,10 +56,36 @@ void test3() BOOST_TEST(x.i() == 2); } +class C3 { +public: + explicit C3(int i) + : i_(i) { } + C3(const C3& c) + : i_(c.i_) { } + C3& operator=(const C1& c) { + i_ = c.i(); + return *this; + } + int i() const { + return i_; + } +private: + C3& operator=(const C3&); + int i_; +}; + +void test4() +{ + C3 x(1); + BOOST_TEST(boost::exchange(x, C1(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + int main() { test1(); test2(); test3(); + test4(); return boost::report_errors(); }