[ox/std] Fix alignment of Vector elements

This commit is contained in:
Gary Talent 2019-07-19 22:11:01 -05:00
parent 32d7c7b9e2
commit 22378d0a9f
2 changed files with 16 additions and 6 deletions

View File

@ -57,6 +57,16 @@ typedef uint32_t uintptr_t;
namespace ox { namespace ox {
/**
* Aliases type T in size and alignment to allow allocating space for a T
* without running the constructor.
*/
template<typename T>
struct alignas(alignof(T)) AllocAlias {
char buff[sizeof(T)];
};
template<std::size_t sz> template<std::size_t sz>
struct SignedType { struct SignedType {
}; };

View File

@ -85,7 +85,7 @@ template<typename T>
Vector<T>::Vector(std::size_t size) noexcept { Vector<T>::Vector(std::size_t size) noexcept {
m_size = size; m_size = size;
m_cap = m_size; m_cap = m_size;
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]); m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; i++) {
m_items[i] = {}; m_items[i] = {};
} }
@ -95,7 +95,7 @@ template<typename T>
Vector<T>::Vector(Vector<T> &other) noexcept { Vector<T>::Vector(Vector<T> &other) noexcept {
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]); m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
for (std::size_t i = 0; i < m_size; i++) { for (std::size_t i = 0; i < m_size; i++) {
m_items[i] = ox::move(other.m_items[i]); m_items[i] = ox::move(other.m_items[i]);
} }
@ -118,7 +118,7 @@ Vector<T>::~Vector() noexcept {
m_items[i].~T(); m_items[i].~T();
} }
} }
delete[] reinterpret_cast<char*>(m_items); delete[] reinterpret_cast<AllocAlias<T>*>(m_items);
m_items = nullptr; m_items = nullptr;
} }
@ -127,7 +127,7 @@ Vector<T> &Vector<T>::operator=(Vector<T> &other) noexcept {
this->~Vector<T>(); this->~Vector<T>();
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]); m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
for (std::size_t i = 0; i < m_size; i++) { for (std::size_t i = 0; i < m_size; i++) {
m_items[i] = other.m_items[i]; m_items[i] = other.m_items[i];
} }
@ -249,7 +249,7 @@ template<typename T>
void Vector<T>::expandCap(std::size_t cap) noexcept { void Vector<T>::expandCap(std::size_t cap) noexcept {
auto oldItems = m_items; auto oldItems = m_items;
m_cap = cap; m_cap = cap;
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]); m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
if (oldItems) { // move over old items if (oldItems) { // move over old items
const auto itRange = cap > m_size ? m_size : cap; const auto itRange = cap > m_size ? m_size : cap;
for (std::size_t i = 0; i < itRange; i++) { for (std::size_t i = 0; i < itRange; i++) {
@ -258,7 +258,7 @@ void Vector<T>::expandCap(std::size_t cap) noexcept {
for (std::size_t i = itRange; i < m_cap; i++) { for (std::size_t i = itRange; i < m_cap; i++) {
new (&m_items[i]) T; new (&m_items[i]) T;
} }
delete[] reinterpret_cast<char*>(m_items); delete[] reinterpret_cast<AllocAlias<T>*>(m_items);
} }
} }