mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 14:13:23 +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
1 changed files with 19 additions and 29 deletions
|
@ -163,14 +163,10 @@ template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
||||||
class vector {
|
class vector {
|
||||||
#define SIZE_IDX -1
|
#define SIZE_IDX -1
|
||||||
#define CAPACITY_IDX -2
|
#define CAPACITY_IDX -2
|
||||||
T * m_data;
|
T * m_data = nullptr;
|
||||||
|
|
||||||
void destroy_elements() {
|
void destroy_elements() {
|
||||||
iterator it = begin();
|
std::destroy_n(m_data, size());
|
||||||
iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_memory() {
|
void free_memory() {
|
||||||
|
@ -178,17 +174,21 @@ class vector {
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_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) {
|
if (m_data == nullptr) {
|
||||||
SZ capacity = 2;
|
SZ capacity = 2;
|
||||||
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
||||||
*mem = capacity;
|
*mem = capacity;
|
||||||
mem++;
|
mem++;
|
||||||
*mem = 0;
|
*mem = 0;
|
||||||
mem++;
|
mem++;
|
||||||
m_data = reinterpret_cast<T *>(mem);
|
m_data = reinterpret_cast<T *>(mem);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
static_assert(std::is_nothrow_move_constructible<T>::value, "");
|
static_assert(std::is_nothrow_move_constructible<T>::value);
|
||||||
SASSERT(capacity() > 0);
|
SASSERT(capacity() > 0);
|
||||||
SZ old_capacity = reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
SZ old_capacity = reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
||||||
SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2;
|
SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2;
|
||||||
|
@ -203,15 +203,12 @@ class vector {
|
||||||
m_data = reinterpret_cast<T *>(mem + 2);
|
m_data = reinterpret_cast<T *>(mem + 2);
|
||||||
} else {
|
} else {
|
||||||
mem = (SZ*)memory::allocate(new_capacity_T);
|
mem = (SZ*)memory::allocate(new_capacity_T);
|
||||||
auto old_data = m_data;
|
|
||||||
auto old_size = size();
|
auto old_size = size();
|
||||||
mem[1] = old_size;
|
mem[1] = old_size;
|
||||||
m_data = reinterpret_cast<T *>(mem + 2);
|
auto new_data = reinterpret_cast<T *>(mem + 2);
|
||||||
for (unsigned i = 0; i < old_size; ++i) {
|
std::uninitialized_move_n(m_data, old_size, new_data);
|
||||||
new (&m_data[i]) T(std::move(old_data[i]));
|
destroy();
|
||||||
old_data[i].~T();
|
m_data = new_data;
|
||||||
}
|
|
||||||
memory::deallocate(old_mem);
|
|
||||||
}
|
}
|
||||||
*mem = new_capacity;
|
*mem = new_capacity;
|
||||||
}
|
}
|
||||||
|
@ -243,12 +240,9 @@ public:
|
||||||
typedef T * iterator;
|
typedef T * iterator;
|
||||||
typedef const T * const_iterator;
|
typedef const T * const_iterator;
|
||||||
|
|
||||||
vector():
|
vector() = default;
|
||||||
m_data(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(SZ s) {
|
vector(SZ s) {
|
||||||
m_data = nullptr;
|
|
||||||
init(s);
|
init(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,25 +265,22 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector(SZ s, T const & elem):
|
vector(SZ s, T const & elem) {
|
||||||
m_data(nullptr) {
|
|
||||||
resize(s, elem);
|
resize(s, elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector(vector const & source):
|
vector(vector const & source) {
|
||||||
m_data(nullptr) {
|
|
||||||
if (source.m_data) {
|
if (source.m_data) {
|
||||||
copy_core(source);
|
copy_core(source);
|
||||||
}
|
}
|
||||||
SASSERT(size() == source.size());
|
SASSERT(size() == source.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
vector(vector&& other) noexcept : m_data(nullptr) {
|
vector(vector&& other) noexcept {
|
||||||
std::swap(m_data, other.m_data);
|
std::swap(m_data, other.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector(SZ s, T const * data):
|
vector(SZ s, T const * data) {
|
||||||
m_data(nullptr) {
|
|
||||||
for (SZ i = 0; i < s; i++) {
|
for (SZ i = 0; i < s; i++) {
|
||||||
push_back(data[i]);
|
push_back(data[i]);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +312,6 @@ public:
|
||||||
bool operator!=(vector const & other) const {
|
bool operator!=(vector const & other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector & operator=(vector const & source) {
|
vector & operator=(vector const & source) {
|
||||||
if (this == &source) {
|
if (this == &source) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue