Code refactor: add some array utility methods, fix leak in assignment operator.

This commit is contained in:
Brecht Van Lommel
2016-05-07 19:47:08 +02:00
parent df8097ea2a
commit 93e4ae84ad

View File

@@ -114,33 +114,42 @@ public:
array(const array& from) array(const array& from)
{ {
*this = from; if(from.datasize_ == 0) {
}
array& operator=(const array& from)
{
if(from.datasize == 0) {
data_ = NULL; data_ = NULL;
datasize_ = 0; datasize_ = 0;
capacity_ = 0; capacity_ = 0;
} }
else { else {
data_ = mem_allocate(from.datasize); data_ = mem_allocate(from.datasize_);
memcpy(data_, from.data, from.datasize*sizeof(T)); memcpy(data_, from.data_, from.datasize_*sizeof(T));
datasize_ = from.datasize_; datasize_ = from.datasize_;
capacity_ = datasize_; capacity_ = datasize_;
} }
}
array& operator=(const array& from)
{
if(this != &from) {
clear();
if(from.datasize_ > 0) {
data_ = mem_allocate(from.datasize_);
memcpy(data_, from.data_, from.datasize_*sizeof(T));
datasize_ = from.datasize_;
capacity_ = datasize_;
}
}
return *this; return *this;
} }
array& operator=(const vector<T>& from) array& operator=(const vector<T>& from)
{ {
datasize_ = from.size(); clear();
capacity_ = datasize_;
data_ = NULL;
if(datasize_ > 0) { if(from.size() > 0) {
datasize_ = from.size();
capacity_ = datasize_;
data_ = mem_allocate(datasize_); data_ = mem_allocate(datasize_);
memcpy(data_, &from[0], datasize_*sizeof(T)); memcpy(data_, &from[0], datasize_*sizeof(T));
} }
@@ -153,27 +162,44 @@ public:
mem_free(data_, capacity_); mem_free(data_, capacity_);
} }
bool operator==(const vector<T>& other)
{
if (datasize_ != other.datasize_)
return false;
return memcmp(data_, other.data_, datasize_*sizeof(T)) == 0;
}
void steal_data(array& from)
{
if (this != &from)
{
clear();
data_ = from.data_;
datasize_ = from.datasize_;
capacity_ = from.capacity_;
from.data_ = NULL;
from.datasize_ = 0;
from.capacity_ = 0;
}
}
T* resize(size_t newsize) T* resize(size_t newsize)
{ {
if(newsize == 0) { if(newsize == 0) {
clear(); clear();
} }
else if(newsize != datasize_) { else if(newsize != capacity_) {
if(newsize > capacity_) { T *newdata = mem_allocate(newsize);
T *newdata = mem_allocate(newsize); if(data_ != NULL) {
if(newdata == NULL) { memcpy(newdata, data_, ((datasize_ < newsize)? datasize_: newsize)*sizeof(T));
/* Allocation failed, likely out of memory. */ mem_free(data_, capacity_);
clear();
return NULL;
}
else if(data_ != NULL) {
memcpy(newdata, data_, ((datasize_ < newsize)? datasize_: newsize)*sizeof(T));
mem_free(data_, capacity_);
}
data_ = newdata;
capacity_ = newsize;
} }
data_ = newdata;
datasize_ = newsize; datasize_ = newsize;
capacity_ = newsize;
} }
return data_; return data_;
} }
@@ -188,18 +214,29 @@ public:
capacity_ = 0; capacity_ = 0;
} }
size_t empty() const
{
return datasize_ == 0;
}
size_t size() const size_t size() const
{ {
return datasize_; return datasize_;
} }
const T* data() const
{
return data_;
}
T& operator[](size_t i) const T& operator[](size_t i) const
{ {
assert(i < datasize_); assert(i < datasize_);
return data_[i]; return data_[i];
} }
void reserve(size_t newcapacity) { void reserve(size_t newcapacity)
{
if(newcapacity > capacity_) { if(newcapacity > capacity_) {
T *newdata = mem_allocate(newcapacity); T *newdata = mem_allocate(newcapacity);
if(data_ != NULL) { if(data_ != NULL) {
@@ -211,10 +248,28 @@ public:
} }
} }
size_t capacity() const { size_t capacity() const
{
return capacity_; return capacity_;
} }
// do not use this method unless you are sure the code is not performance critical
void push_back_slow(const T& t)
{
if (capacity_ == datasize_)
{
reserve(datasize_ == 0 ? 1 : (size_t)((datasize_ + 1) * 1.2));
}
data_[datasize_++] = t;
}
void push_back_reserved(const T& t)
{
assert(datasize_ < capacity_);
push_back_slow(t);
}
protected: protected:
inline T* mem_allocate(size_t N) inline T* mem_allocate(size_t N)
{ {