diff --git a/src/util/vector.h b/src/util/vector.h index a3787d300a..665569c03c 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -163,14 +163,10 @@ template class vector { #define SIZE_IDX -1 #define CAPACITY_IDX -2 - T * m_data; + T * m_data = nullptr; void destroy_elements() { - iterator it = begin(); - iterator e = end(); - for (; it != e; ++it) { - it->~T(); - } + std::destroy_n(m_data, size()); } void free_memory() { @@ -178,17 +174,21 @@ class vector { } void expand_vector() { + // ensure that the data is sufficiently aligned + // better fail to compile than produce code that may crash + static_assert((sizeof(SZ) * 2) % alignof(T) == 0); + if (m_data == nullptr) { SZ capacity = 2; SZ * mem = reinterpret_cast(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2)); - *mem = capacity; + *mem = capacity; mem++; - *mem = 0; + *mem = 0; mem++; - m_data = reinterpret_cast(mem); + m_data = reinterpret_cast(mem); } else { - static_assert(std::is_nothrow_move_constructible::value, ""); + static_assert(std::is_nothrow_move_constructible::value); SASSERT(capacity() > 0); SZ old_capacity = reinterpret_cast(m_data)[CAPACITY_IDX]; SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2; @@ -203,15 +203,12 @@ class vector { m_data = reinterpret_cast(mem + 2); } else { mem = (SZ*)memory::allocate(new_capacity_T); - auto old_data = m_data; auto old_size = size(); mem[1] = old_size; - m_data = reinterpret_cast(mem + 2); - for (unsigned i = 0; i < old_size; ++i) { - new (&m_data[i]) T(std::move(old_data[i])); - old_data[i].~T(); - } - memory::deallocate(old_mem); + auto new_data = reinterpret_cast(mem + 2); + std::uninitialized_move_n(m_data, old_size, new_data); + destroy(); + m_data = new_data; } *mem = new_capacity; } @@ -243,12 +240,9 @@ class vector { typedef T * iterator; typedef const T * const_iterator; - vector(): - m_data(nullptr) { - } + vector() = default; vector(SZ s) { - m_data = nullptr; init(s); } @@ -271,25 +265,22 @@ class vector { } } - vector(SZ s, T const & elem): - m_data(nullptr) { + vector(SZ s, T const & elem) { resize(s, elem); } - vector(vector const & source): - m_data(nullptr) { + vector(vector const & source) { if (source.m_data) { copy_core(source); } SASSERT(size() == source.size()); } - vector(vector&& other) noexcept : m_data(nullptr) { + vector(vector&& other) noexcept { std::swap(m_data, other.m_data); } - vector(SZ s, T const * data): - m_data(nullptr) { + vector(SZ s, T const * data) { for (SZ i = 0; i < s; i++) { push_back(data[i]); } @@ -321,7 +312,6 @@ class vector { bool operator!=(vector const & other) const { return !(*this == other); } - vector & operator=(vector const & source) { if (this == &source) {