diff options
-rw-r--r-- | absl/debugging/symbolize_win32.inc | 2 | ||||
-rw-r--r-- | absl/utility/utility.h | 22 | ||||
-rw-r--r-- | absl/utility/utility_test.cc | 8 |
3 files changed, 31 insertions, 1 deletions
diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc index c300c50a..e3fff74d 100644 --- a/absl/debugging/symbolize_win32.inc +++ b/absl/debugging/symbolize_win32.inc @@ -40,7 +40,7 @@ void InitializeSymbolizer(const char *argv0) { SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME); if (!SymInitialize(process, nullptr, true)) { // GetLastError() returns a Win32 DWORD, but we assign to - // unsigned long to simplify the ABSL_RAW_LOG case below. The uniform + // unsigned long long to simplify the ABSL_RAW_LOG case below. The uniform // initialization guarantees this is not a narrowing conversion. const unsigned long long error{GetLastError()}; // NOLINT(runtime/int) ABSL_RAW_LOG(FATAL, "SymInitialize() failed: %llu", error); diff --git a/absl/utility/utility.h b/absl/utility/utility.h index 5b9b84e0..d73602c4 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -24,6 +24,7 @@ // * make_index_sequence<N> == std::make_index_sequence<N> // * index_sequence_for<Ts...> == std::index_sequence_for<Ts...> // * apply<Functor, Tuple> == std::apply<Functor, Tuple> +// * exchange<T> == std::exchange<T> // // 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<std::tuple_size< typename std::remove_reference<Tuple>::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 <typename T, typename U = T> +T exchange(T& obj, U&& new_value) { + T old_value = absl::move(obj); + obj = absl::forward<U>(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 342165ed..3c447b20 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 |