Skip to content

Commit

Permalink
Merge pull request #1378 from NVIDIA/utility-improvements
Browse files Browse the repository at this point in the history
Make `__manual_lifetime` and `__indestructible` `constinit` constructible
  • Loading branch information
ericniebler authored Jul 20, 2024
2 parents 9428f35 + ccdc87b commit bfc2610
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 17 deletions.
26 changes: 12 additions & 14 deletions include/exec/__detail/__manual_lifetime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ namespace exec {
template <class _Ty>
class __manual_lifetime {
public:
__manual_lifetime() noexcept {
constexpr __manual_lifetime() noexcept {
}

~__manual_lifetime() {
constexpr ~__manual_lifetime() {
}

__manual_lifetime(const __manual_lifetime&) = delete;
Expand All @@ -43,39 +43,37 @@ namespace exec {
auto
__construct(_Args&&... __args) noexcept(stdexec::__nothrow_constructible_from<_Ty, _Args...>)
-> _Ty& {
return *::new (static_cast<void*>(std::addressof(__value_)))
_Ty(static_cast<_Args&&>(__args)...);
return *std::construct_at(&__get(), static_cast<_Args&&>(__args)...);
}

template <class _Func>
auto __construct_with(_Func&& func) -> _Ty& {
return *::new (static_cast<void*>(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<void*>(__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<const _Ty*>(__buffer_);
}

auto __get() const && noexcept -> const _Ty&& {
return static_cast<const _Ty&&>(__value_);
return static_cast<const _Ty&&>(*reinterpret_cast<const _Ty*>(__buffer_));
}

private:
union {
_Ty __value_;
};
alignas(_Ty) unsigned char __buffer_[sizeof(_Ty)]{};
};
} // namespace exec
3 changes: 3 additions & 0 deletions include/stdexec/__detail/__operation_states.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include <type_traits>

namespace stdexec {
// operation state tag type
struct operation_state_t { };

/////////////////////////////////////////////////////////////////////////////
// [execution.op_state]
namespace __start {
Expand Down
6 changes: 3 additions & 3 deletions include/stdexec/__detail/__utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ namespace stdexec {
template <class _Ty>
struct __indestructible {
template <class... _Us>
__indestructible(_Us&&... __us) noexcept(__nothrow_constructible_from<_Ty, _Us...>) {
::new (static_cast<void*>(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 {
Expand Down

0 comments on commit bfc2610

Please sign in to comment.