Skip to content

Commit 8e32727

Browse files
authored
Merge pull request #2010 from ericniebler/swapping-big-any-and-small-any
handle swapping two `__any` objects when one is in situ and the other is on the heap
2 parents d114568 + 2cc2e2f commit 8e32727

File tree

2 files changed

+286
-243
lines changed

2 files changed

+286
-243
lines changed

include/stdexec/__detail/__any.hpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -916,14 +916,14 @@ namespace STDEXEC::__any
916916
return std::swap(__this_ptr, __that_ptr);
917917

918918
if (__this_ptr == nullptr)
919-
return __value(__other).__move_to(__root_ptr_, __buff_);
919+
return __other.__move_to_empty(*this);
920920

921921
if (__that_ptr == nullptr)
922-
return __value(*this).__move_to(__other.__root_ptr_, __other.__buff_);
922+
return (*this).__move_to_empty(__other);
923923

924-
auto temp = std::move(*this);
925-
__value(__other).__move_to(__root_ptr_, __buff_);
926-
__value(temp).__move_to(__other.__root_ptr_, __other.__buff_);
924+
auto __temp = std::move(*this);
925+
__other.__move_to_empty(*this);
926+
__temp.__move_to_empty(__other);
927927
}
928928
}
929929

@@ -1050,6 +1050,31 @@ namespace STDEXEC::__any
10501050
}
10511051
}
10521052

1053+
constexpr void __move_to_empty(__value_proxy_root &__other) noexcept
1054+
requires __movable
1055+
{
1056+
STDEXEC_IF_CONSTEVAL
1057+
{
1058+
__other.__root_ptr_ = std::exchange(__root_ptr_, nullptr);
1059+
}
1060+
else
1061+
{
1062+
STDEXEC_ASSERT(!__empty(*this));
1063+
STDEXEC_ASSERT(__empty(__other));
1064+
auto &__this_ptr = *__std::start_lifetime_as<__tagged_ptr>(__buff_);
1065+
auto &__that_ptr = *__std::start_lifetime_as<__tagged_ptr>(__other.__buff_);
1066+
if (__this_ptr.__is_tagged())
1067+
{
1068+
__that_ptr = std::exchange(__this_ptr, nullptr);
1069+
}
1070+
else
1071+
{
1072+
__value(*this).__move_to(__other.__root_ptr_, __other.__buff_);
1073+
__reset(*this);
1074+
}
1075+
}
1076+
}
1077+
10531078
STDEXEC_ATTRIBUTE(always_inline)
10541079
constexpr void __reset_() noexcept final
10551080
{

0 commit comments

Comments
 (0)