From 699d71150a45f9fc4173f39dadc740465b854595 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:19:14 +0800 Subject: [PATCH 1/3] benchmark --- benchmarks/CMakeLists.txt | 1 + benchmarks/src/any_swap.cpp | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 benchmarks/src/any_swap.cpp 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(); From 2944511990a373f97c46f052e750e32760ecf04d Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:20:36 +0800 Subject: [PATCH 2/3] Step 1 --- stl/inc/any | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stl/inc/any b/stl/inc/any index 2f33cb0545..4a2f798d53 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -230,7 +230,9 @@ public: } void swap(any& _That) noexcept { - _That = _STD exchange(*this, _STD move(_That)); + any _Old = _STD move(*this); + *this = _STD move(_That); + _That = _STD move(_Old); } // Observers [any.observers] From 5567c9c5703b4040f2c004a20ca26a40a549ff39 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:22:00 +0800 Subject: [PATCH 3/3] Step 2 --- stl/inc/any | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/any b/stl/inc/any index 4a2f798d53..d0e2ea6a4c 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -231,8 +231,9 @@ public: void swap(any& _That) noexcept { any _Old = _STD move(*this); - *this = _STD move(_That); - _That = _STD move(_Old); + _Assign(_STD move(_That)); + _That.reset(); + _That._Move_from(_Old); } // Observers [any.observers]