Code refactor: add some array utility methods, fix leak in assignment operator.
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user