From 2cd4753a02634a9f15e23e87ca8c176f3e296f1f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 7 Jul 2018 23:13:03 -0400 Subject: [PATCH] Implement boost::exchange --- include/boost/core/exchange.hpp | 47 +++++++++++++++++++++ test/Jamfile.v2 | 3 ++ test/exchange_move_test.cpp | 73 +++++++++++++++++++++++++++++++++ test/exchange_test.cpp | 65 +++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 include/boost/core/exchange.hpp create mode 100644 test/exchange_move_test.cpp create mode 100644 test/exchange_test.cpp diff --git a/include/boost/core/exchange.hpp b/include/boost/core/exchange.hpp new file mode 100644 index 0000000..c31f2af --- /dev/null +++ b/include/boost/core/exchange.hpp @@ -0,0 +1,47 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_EXCHANGE_HPP +#define BOOST_CORE_EXCHANGE_HPP + +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +namespace boost { + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +template +BOOST_CXX14_CONSTEXPR inline T exchange(T& t, U&& u) +{ + T v = std::move(t); + t = std::forward(u); + return v; +} +#else +namespace detail { + +template +struct exchanger { + typedef T type; +}; + +} /* detail */ + +template +inline T exchange(T& t, const typename detail::exchanger::type& u) +{ + T v = t; + t = u; + return v; +} +#endif + +} /* boost */ + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 66b96fc..ba801e6 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -121,5 +121,8 @@ run pointer_traits_rebind_test.cpp ; run pointer_traits_pointer_to_test.cpp ; run to_address_test.cpp ; +run exchange_test.cpp ; +run exchange_move_test.cpp ; + use-project /boost/core/swap : ./swap ; build-project ./swap ; diff --git a/test/exchange_move_test.cpp b/test/exchange_move_test.cpp new file mode 100644 index 0000000..57255b8 --- /dev/null +++ b/test/exchange_move_test.cpp @@ -0,0 +1,73 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#include + +class C1 { +public: + explicit C1(int i) + : i_(i) { } + C1(C1&& c) + : i_(c.i_) { } + C1& operator=(C1&& c) { + i_ = c.i_; + return *this; + } + int i() const { + return i_; + } +private: + C1(const C1&); + C1& operator=(const C1&); + int i_; +}; + +void test1() +{ + C1 x(1); + BOOST_TEST(boost::exchange(x, C1(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + +class C2 { +public: + explicit C2(int i) + : i_(i) { } + operator C1() const { + return C1(i_); + } + int i() const { + return i_; + } +private: + C2(const C2&); + C2& operator=(const C2&); + int i_; +}; + +void test2() +{ + C1 x(1); + BOOST_TEST(boost::exchange(x, C2(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + +int main() +{ + test1(); + test2(); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/test/exchange_test.cpp b/test/exchange_test.cpp new file mode 100644 index 0000000..a370d11 --- /dev/null +++ b/test/exchange_test.cpp @@ -0,0 +1,65 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +void test1() +{ + int i = 1; + BOOST_TEST(boost::exchange(i, 2) == 1); + BOOST_TEST(i == 2); +} + +class C1 { +public: + explicit C1(int i) + : i_(i) { } + int i() const { + return i_; + } +private: + int i_; +}; + +void test2() +{ + C1 x(1); + BOOST_TEST(boost::exchange(x, C1(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + +class C2 { +public: + explicit C2(int i) + : i_(i) { } + operator C1() const { + return C1(i_); + } + int i() const { + return i_; + } +private: + C2(const C2&); + C2& operator=(const C2&); + int i_; +}; + +void test3() +{ + C1 x(1); + BOOST_TEST(boost::exchange(x, C2(2)).i() == 1); + BOOST_TEST(x.i() == 2); +} + +int main() +{ + test1(); + test2(); + test3(); + return boost::report_errors(); +}