[ox/std] Fix alignment of Optional's buffer

This commit is contained in:
Gary Talent 2023-02-07 01:31:35 -06:00
parent d571d49cce
commit 5de5eee215
2 changed files with 13 additions and 5 deletions

View File

@ -22,7 +22,7 @@ template<typename T, std::size_t buffSize = sizeof(T)>
class Optional { class Optional {
private: private:
T *m_ptr = nullptr; T *m_ptr = nullptr;
char m_data[buffSize] = {}; AllocAlias<T> m_data = {};
public: public:
constexpr Optional() noexcept = default; constexpr Optional() noexcept = default;
@ -32,7 +32,7 @@ class Optional {
constexpr Optional(const Optional &other) { constexpr Optional(const Optional &other) {
if (other.m_ptr) { if (other.m_ptr) {
m_ptr = new(m_data) T(*other.m_ptr); m_ptr = new(m_data.data()) T(*other.m_ptr);
} }
} }
@ -41,7 +41,7 @@ class Optional {
m_ptr->~T(); m_ptr->~T();
} }
if (other.m_ptr) { if (other.m_ptr) {
m_ptr = new(m_data) T(std::move(*other.m_ptr)); m_ptr = new(m_data.data()) T(std::move(*other.m_ptr));
} }
} }
@ -120,7 +120,7 @@ class Optional {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_ptr = new T(ox::forward<Args>(args)...); m_ptr = new T(ox::forward<Args>(args)...);
} else { } else {
m_ptr = std::construct_at<T>(reinterpret_cast<T*>(m_data), ox::forward<Args>(args)...); m_ptr = std::construct_at<T>(reinterpret_cast<T*>(m_data.data()), ox::forward<Args>(args)...);
} }
return *m_ptr; return *m_ptr;
} }
@ -131,7 +131,7 @@ class Optional {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_ptr = new U(ox::forward<Args>(args)...); m_ptr = new U(ox::forward<Args>(args)...);
} else { } else {
m_ptr = std::construct_at<U>(reinterpret_cast<T*>(m_data), ox::forward<Args>(args)...); m_ptr = std::construct_at<U>(reinterpret_cast<T*>(m_data.data()), ox::forward<Args>(args)...);
} }
return *m_ptr; return *m_ptr;
} }

View File

@ -67,6 +67,14 @@ template<typename T, std::size_t sz = sizeof(T)>
struct alignas(alignof(T)) AllocAlias { struct alignas(alignof(T)) AllocAlias {
char buff[sz]; char buff[sz];
constexpr AllocAlias() noexcept = default; constexpr AllocAlias() noexcept = default;
[[nodiscard]]
auto data() noexcept {
return reinterpret_cast<T*>(this);
}
[[nodiscard]]
auto data() const noexcept {
return reinterpret_cast<const T*>(this);
}
}; };