15 alignas(Align) std::byte data[Size];
18 [[nodiscard]] T& as() & {
19 if constexpr (std::is_reference_v<T>) {
20 return **
reinterpret_cast<std::remove_reference_t<T>**
>(data);
22 return *
reinterpret_cast<T*
>(data);
26 [[nodiscard]] T
const& as()
const& {
27 if constexpr (std::is_reference_v<T>) {
28 return **
reinterpret_cast<std::remove_reference_t<T> const**
>(data);
30 return *
reinterpret_cast<T const*
>(data);
34 [[nodiscard]] T&& as() && {
35 if constexpr (std::is_reference_v<T>) {
36 return std::move(**
reinterpret_cast<std::remove_reference_t<T>**
>(data));
38 return std::move(*
reinterpret_cast<T*
>(data));
42 [[nodiscard]] T
const&& as()
const&& {
43 if constexpr (std::is_reference_v<T>) {
44 return std::move(**
reinterpret_cast<std::remove_reference_t<T> const**
>(data));
46 return std::move(*
reinterpret_cast<T const*
>(data));
53 alignas(Align) std::byte data[Size];
55 template <
class... Args>
57 std::construct_at(this->operator->(), std::forward<Args>(args)...);
65 constexpr T& operator=(U&& u) {
66 get().operator=(std::forward<U>(u));
71 get().operator=(u.get());
76 get().operator=(std::move(u.get()));
82 [[nodiscard]] T* operator->() {
return reinterpret_cast<T*
>(data); }
83 [[nodiscard]] T
const* operator->()
const {
return reinterpret_cast<T const*
>(data); }
84 [[nodiscard]] T& get() & {
return *
reinterpret_cast<T*
>(data); }
85 [[nodiscard]] T
const& get()
const& {
return *
reinterpret_cast<T const*
>(data); }
86 [[nodiscard]] T&& get() && {
return std::move(*
reinterpret_cast<T*
>(data)); }
87 [[nodiscard]] T
const&& get()
const&& {
return std::move(*
reinterpret_cast<T const*
>(data)); }
88 [[nodiscard]] T& operator*() & {
return get(); }
89 [[nodiscard]] T
const& operator*()
const& {
return get(); }
90 [[nodiscard]] T&& operator*() && {
return std::move(get()); }
91 [[nodiscard]] T
const&& operator*()
const&& {
return std::move(get()); }
92 [[nodiscard]]
operator T&() {
return get(); }
93 [[nodiscard]]
operator T
const&()
const {
return get(); }