diff --git a/libs/pika/execution_base/include/pika/execution_base/any_sender.hpp b/libs/pika/execution_base/include/pika/execution_base/any_sender.hpp index 08032dc16..499131bcb 100644 --- a/libs/pika/execution_base/include/pika/execution_base/any_sender.hpp +++ b/libs/pika/execution_base/include/pika/execution_base/any_sender.hpp @@ -39,6 +39,8 @@ // SBO is currently disabled as it seems to be buggy in certain use cases. It can still be // explicitly forced to on by defining PIKA_DETAIL_ENABLE_ANY_SENDER_SBO. +// TODO: Remove definition or enable unconditionally. +#define PIKA_DETAIL_ENABLE_ANY_SENDER_SBO namespace pika::detail { template @@ -134,7 +136,7 @@ namespace pika::detail { bool using_embedded_storage() const noexcept { #if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO) - return object == reinterpret_cast(&embedded_storage); + return object == static_cast(embedded_storage); #else return false; #endif @@ -169,15 +171,12 @@ namespace pika::detail { #if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO) if (other.using_embedded_storage()) { - auto p = reinterpret_cast(&embedded_storage); - other.get().move_into(p); - object = p; + object = other.get().move_into(embedded_storage); } else #endif { - heap_storage = other.heap_storage; - other.heap_storage = nullptr; + heap_storage = std::exchange(other.heap_storage, nullptr); object = heap_storage; } @@ -198,15 +197,12 @@ namespace pika::detail { #if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO) if (other.using_embedded_storage()) { - auto p = reinterpret_cast(&embedded_storage); - other.get().move_into(p); - object = p; + object = other.get().move_into(embedded_storage); } else #endif { - heap_storage = other.heap_storage; - other.heap_storage = nullptr; + heap_storage = std::exchange(other.heap_storage, nullptr); object = heap_storage; } @@ -276,9 +272,7 @@ namespace pika::detail { #if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO) if constexpr (can_use_embedded_storage()) { - Impl* p = reinterpret_cast(&embedded_storage); - new (p) Impl(std::forward(ts)...); - object = p; + object = new (embedded_storage) Impl(std::forward(ts)...); } else #endif @@ -323,9 +317,7 @@ namespace pika::detail { #if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO) if (other.using_embedded_storage()) { - base_type* p = reinterpret_cast(&embedded_storage); - other.get().clone_into(p); - object = p; + object = other.get().clone_into(embedded_storage); } else #endif @@ -581,7 +573,7 @@ namespace pika::execution::experimental::detail { struct unique_any_sender_base { virtual ~unique_any_sender_base() noexcept = default; - virtual void move_into(void* p) = 0; + virtual unique_any_sender_base* move_into(unsigned char* p) = 0; virtual any_operation_state_holder connect(any_receiver&& receiver) && = 0; virtual bool empty() const noexcept { return false; } }; @@ -589,8 +581,9 @@ namespace pika::execution::experimental::detail { template struct any_sender_base : public unique_any_sender_base { + virtual any_sender_base* move_into(unsigned char* p) = 0; virtual any_sender_base* clone() const = 0; - virtual void clone_into(void* p) const = 0; + virtual any_sender_base* clone_into(unsigned char* p) const = 0; using unique_any_sender_base::connect; virtual any_operation_state_holder connect(any_receiver&& receiver) const& = 0; }; @@ -598,7 +591,7 @@ namespace pika::execution::experimental::detail { template struct empty_unique_any_sender final : unique_any_sender_base { - void move_into(void*) override { PIKA_UNREACHABLE; } + unique_any_sender_base* move_into(unsigned char*) override { PIKA_UNREACHABLE; } bool empty() const noexcept override { return true; } @@ -611,11 +604,11 @@ namespace pika::execution::experimental::detail { template struct empty_any_sender final : any_sender_base { - void move_into(void*) override { PIKA_UNREACHABLE; } + any_sender_base* move_into(unsigned char*) override { PIKA_UNREACHABLE; } any_sender_base* clone() const override { PIKA_UNREACHABLE; } - void clone_into(void*) const override { PIKA_UNREACHABLE; } + any_sender_base* clone_into(unsigned char*) const override { PIKA_UNREACHABLE; } bool empty() const noexcept override { return true; } @@ -645,7 +638,10 @@ namespace pika::execution::experimental::detail { ~unique_any_sender_impl() noexcept = default; - void move_into(void* p) override { new (p) unique_any_sender_impl(std::move(sender)); } + unique_any_sender_base* move_into(unsigned char* p) override + { + return new (p) unique_any_sender_impl(std::move(sender)); + } any_operation_state_holder connect(any_receiver&& receiver) && override { @@ -667,11 +663,17 @@ namespace pika::execution::experimental::detail { ~any_sender_impl() noexcept = default; - void move_into(void* p) override { new (p) any_sender_impl(std::move(sender)); } + any_sender_base* move_into(unsigned char* p) override + { + return new (p) any_sender_impl(std::move(sender)); + } any_sender_base* clone() const override { return new any_sender_impl(sender); } - void clone_into(void* p) const override { new (p) any_sender_impl(sender); } + any_sender_base* clone_into(unsigned char* p) const override + { + return new (p) any_sender_impl(sender); + } any_operation_state_holder connect(any_receiver&& receiver) const& override {