From da9849635b5e5f3255b9abd765f79847aba99062 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 20 Jul 2024 09:34:04 -0700 Subject: [PATCH 1/3] change `__manual_lifetime` so it is `constinit` constructible --- include/exec/__detail/__manual_lifetime.hpp | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/include/exec/__detail/__manual_lifetime.hpp b/include/exec/__detail/__manual_lifetime.hpp index 90a06a5a1..0b61a2c0b 100644 --- a/include/exec/__detail/__manual_lifetime.hpp +++ b/include/exec/__detail/__manual_lifetime.hpp @@ -27,10 +27,10 @@ namespace exec { template class __manual_lifetime { public: - __manual_lifetime() noexcept { + constexpr __manual_lifetime() noexcept { } - ~__manual_lifetime() { + constexpr ~__manual_lifetime() { } __manual_lifetime(const __manual_lifetime&) = delete; @@ -43,39 +43,37 @@ namespace exec { auto __construct(_Args&&... __args) noexcept(stdexec::__nothrow_constructible_from<_Ty, _Args...>) -> _Ty& { - return *::new (static_cast(std::addressof(__value_))) - _Ty(static_cast<_Args&&>(__args)...); + return *std::construct_at(&__get(), static_cast<_Args&&>(__args)...); } template auto __construct_with(_Func&& func) -> _Ty& { - return *::new (static_cast(std::addressof(__value_))) - _Ty((static_cast<_Func&&>(func))()); + // This doesn't use std::construct_at to support the case where the function returns an + // immovable type. + return *::new (static_cast(__buffer_)) _Ty((static_cast<_Func&&>(func))()); } void __destroy() noexcept { - __value_.~_Ty(); + std::destroy_at(&__get()); } auto __get() & noexcept -> _Ty& { - return __value_; + return *reinterpret_cast<_Ty*>(__buffer_); } auto __get() && noexcept -> _Ty&& { - return static_cast<_Ty&&>(__value_); + return static_cast<_Ty&&>(*reinterpret_cast<_Ty*>(__buffer_)); } auto __get() const & noexcept -> const _Ty& { - return __value_; + return *reinterpret_cast(__buffer_); } auto __get() const && noexcept -> const _Ty&& { - return static_cast(__value_); + return static_cast(*reinterpret_cast(__buffer_)); } private: - union { - _Ty __value_; - }; + alignas(_Ty) unsigned char __buffer_[sizeof(_Ty)]{}; }; } // namespace exec From 5b1f4eb9decbbc00176de1c32eb7b92da5669f27 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 20 Jul 2024 09:35:03 -0700 Subject: [PATCH 2/3] change `__indestructible` so it is `constinit` constructible --- include/stdexec/__detail/__utility.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/stdexec/__detail/__utility.hpp b/include/stdexec/__detail/__utility.hpp index d3096f499..0a8ee34b1 100644 --- a/include/stdexec/__detail/__utility.hpp +++ b/include/stdexec/__detail/__utility.hpp @@ -144,11 +144,11 @@ namespace stdexec { template struct __indestructible { template - __indestructible(_Us&&... __us) noexcept(__nothrow_constructible_from<_Ty, _Us...>) { - ::new (static_cast(std::addressof(__value))) _Ty(static_cast<_Us&&>(__us)...); + constexpr __indestructible(_Us&&... __us) noexcept(__nothrow_constructible_from<_Ty, _Us...>) + : __value(static_cast<_Us&&>(__us)...) { } - ~__indestructible() { + constexpr ~__indestructible() { } _Ty& get() noexcept { From ccdc87bd2def2f37f4454abc0f39e5d14ea72066 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 20 Jul 2024 09:36:15 -0700 Subject: [PATCH 3/3] add `operation_state_t` tag type --- include/stdexec/__detail/__operation_states.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/stdexec/__detail/__operation_states.hpp b/include/stdexec/__detail/__operation_states.hpp index 2c7ecdf80..f118fc862 100644 --- a/include/stdexec/__detail/__operation_states.hpp +++ b/include/stdexec/__detail/__operation_states.hpp @@ -24,6 +24,9 @@ #include namespace stdexec { + // operation state tag type + struct operation_state_t { }; + ///////////////////////////////////////////////////////////////////////////// // [execution.op_state] namespace __start {