mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 02:15:19 +00:00
vector.h: add assert to fail compilation if alignment isn't ok
let's see if all buildbots are happy with this..
This commit is contained in:
parent
8fd7226b6f
commit
aef38099bf
|
@ -163,14 +163,10 @@ template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
|||
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<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
||||
*mem = capacity;
|
||||
*mem = capacity;
|
||||
mem++;
|
||||
*mem = 0;
|
||||
*mem = 0;
|
||||
mem++;
|
||||
m_data = reinterpret_cast<T *>(mem);
|
||||
m_data = reinterpret_cast<T *>(mem);
|
||||
}
|
||||
else {
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value, "");
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value);
|
||||
SASSERT(capacity() > 0);
|
||||
SZ old_capacity = reinterpret_cast<SZ *>(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<T *>(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<T *>(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<T *>(mem + 2);
|
||||
std::uninitialized_move_n(m_data, old_size, new_data);
|
||||
destroy();
|
||||
m_data = new_data;
|
||||
}
|
||||
*mem = new_capacity;
|
||||
}
|
||||
|
@ -243,12 +240,9 @@ public:
|
|||
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 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ public:
|
|||
bool operator!=(vector const & other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
vector & operator=(vector const & source) {
|
||||
if (this == &source) {
|
||||
|
|
Loading…
Reference in a new issue