diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index caab5625c6..eefc786904 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -102,6 +102,7 @@ endfunction() add_benchmark(adjacent_difference src/adjacent_difference.cpp) add_benchmark(adjacent_find src/adjacent_find.cpp) +add_benchmark(any_swap src/any_swap.cpp) add_benchmark(bitset_from_string src/bitset_from_string.cpp) add_benchmark(bitset_to_string src/bitset_to_string.cpp) add_benchmark(efficient_nonlocking_print src/efficient_nonlocking_print.cpp) diff --git a/benchmarks/src/any_swap.cpp b/benchmarks/src/any_swap.cpp new file mode 100644 index 0000000000..4d2ec21744 --- /dev/null +++ b/benchmarks/src/any_swap.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include + +using trivial = std::array; +static_assert(std::is_trivially_copyable_v); + +struct small { + std::array c{}; + small() = default; + small(const small&) = default; + small& operator=(const small&) = default; + small(small&&) noexcept = default; + small& operator=(small&&) noexcept = default; + ~small() {} +}; +static_assert(!std::is_trivially_copyable_v); +static_assert(std::is_nothrow_move_constructible_v); + +using large = std::array; + +template +void bm(benchmark::State& state) { + std::any a = T{}; + std::any b = T{}; + + for (auto _ : state) { + a.swap(b); + benchmark::DoNotOptimize(a); + benchmark::DoNotOptimize(b); + } +} + +BENCHMARK(bm); +BENCHMARK(bm); +BENCHMARK(bm); + +BENCHMARK_MAIN(); diff --git a/stl/inc/any b/stl/inc/any index 2f33cb0545..d0e2ea6a4c 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -230,7 +230,10 @@ public: } void swap(any& _That) noexcept { - _That = _STD exchange(*this, _STD move(_That)); + any _Old = _STD move(*this); + _Assign(_STD move(_That)); + _That.reset(); + _That._Move_from(_Old); } // Observers [any.observers]