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 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 { 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 {