From ea0e750e52ee223db34a242f9a7229ac04a0f473 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 25 Apr 2018 10:38:08 -0700 Subject: - 2f6a3c92ce0f64e0923ad326ec5d07eae03061fd Add C++14's std::exchange to absl/utility/utility.h. by Abseil Team - 9f2c9adbf998dd9062c8cc3da1076bde87081d71 Fix comment typo. by Greg Falcon GitOrigin-RevId: 2f6a3c92ce0f64e0923ad326ec5d07eae03061fd Change-Id: I7b9db94ad315092baefe56b02f250acadafbe312 --- absl/utility/utility.h | 22 ++++++++++++++++++++++ absl/utility/utility_test.cc | 8 ++++++++ 2 files changed, 30 insertions(+) (limited to 'absl/utility') diff --git a/absl/utility/utility.h b/absl/utility/utility.h index 5b9b84e05d84..d73602c47d3b 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -24,6 +24,7 @@ // * make_index_sequence == std::make_index_sequence // * index_sequence_for == std::index_sequence_for // * apply == std::apply +// * exchange == std::exchange // // This header file also provides the tag types `in_place_t`, `in_place_type_t`, // and `in_place_index_t`, as well as the constant `in_place`, and @@ -264,6 +265,27 @@ auto apply(Functor&& functor, Tuple&& t) absl::make_index_sequence::type>::value>{}); } + +// exchange +// +// Replaces the value of `obj` with `new_value` and returns the old value of +// `obj`. `absl::exchange` is designed to be a drop-in replacement for C++14's +// `std::exchange`. +// +// Example: +// +// Foo& operator=(Foo&& other) { +// ptr1_ = absl::exchange(other.ptr1_, nullptr); +// int1_ = absl::exchange(other.int1_, -1); +// return *this; +// } +template +T exchange(T& obj, U&& new_value) { + T old_value = absl::move(obj); + obj = absl::forward(new_value); + return old_value; +} + } // namespace absl #endif // ABSL_UTILITY_UTILITY_H_ diff --git a/absl/utility/utility_test.cc b/absl/utility/utility_test.cc index 342165ed5240..3c447b20bb04 100644 --- a/absl/utility/utility_test.cc +++ b/absl/utility/utility_test.cc @@ -333,5 +333,13 @@ TEST(ApplyTest, FlipFlop) { EXPECT_EQ(42, absl::apply(&FlipFlop::member, std::make_tuple(obj))); } +TEST(ExchangeTest, MoveOnly) { + auto a = Factory(1); + EXPECT_EQ(1, *a); + auto b = absl::exchange(a, Factory(2)); + EXPECT_EQ(2, *a); + EXPECT_EQ(1, *b); +} + } // namespace -- cgit 1.4.1