[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 {
private:
T *m_ptr = nullptr;
char m_data[buffSize] = {};
AllocAlias<T> m_data = {};
public:
constexpr Optional() noexcept = default;
@ -32,7 +32,7 @@ class Optional {
constexpr Optional(const Optional &other) {
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();
}
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()) {
m_ptr = new T(ox::forward<Args>(args)...);
} 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;
}
@ -131,7 +131,7 @@ class Optional {
if (std::is_constant_evaluated()) {
m_ptr = new U(ox::forward<Args>(args)...);
} 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;
}

View File

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