array growth/shrinkage/reserve system

master
Aaron 5 days ago
parent 9321846172
commit 0db503a9f5

Binary file not shown.

@ -11,6 +11,7 @@ namespace amsmathutil25
void test_amsarray_sort(); void test_amsarray_sort();
void test_amsarray_select(); void test_amsarray_select();
void test_amsarray_sort1(); void test_amsarray_sort1();
void test_amsarray_insertdelete1();

@ -13,6 +13,9 @@ namespace ams
{ {
public: public:
amsarray_size_t length; amsarray_size_t length;
amsarray_size_t reserved;
double growfactor;
T *data; T *data;
//Rule of 5 boilerplate //Rule of 5 boilerplate
@ -37,8 +40,17 @@ namespace ams
// amsarray_failure. // amsarray_failure.
int resize(amsarray_size_t _newlen); int resize(amsarray_size_t _newlen);
//resizing routine for insertions/erasures,
//adjusts reserved capacity according to the growth factor
int resize_insert(amsarray_size_t _newlen);
int reserve(amsarray_size_t _newcap);
int shrink_to_fit();
//returns the array length for routines that expect size() to be present //returns the array length for routines that expect size() to be present
const amsarray_size_t size() const; const amsarray_size_t size() const; //returns length
const amsarray_size_t capacity() const; //returns reserved
T& operator[](amsarray_size_t ind); T& operator[](amsarray_size_t ind);
const T& operator[](amsarray_size_t ind) const; const T& operator[](amsarray_size_t ind) const;

@ -7,6 +7,8 @@ namespace ams
template<typename T> amsarray<T>::amsarray() template<typename T> amsarray<T>::amsarray()
{ {
length = 0; length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL; data = NULL;
return; return;
} }
@ -14,6 +16,8 @@ namespace ams
template<typename T> amsarray<T>::~amsarray() template<typename T> amsarray<T>::~amsarray()
{ {
length = 0; length = 0;
reserved = 0;
growfactor = 1.5;
if(data!=NULL) {delete[] data; data = NULL;} if(data!=NULL) {delete[] data; data = NULL;}
return; return;
} }
@ -23,22 +27,28 @@ namespace ams
return this->length; return this->length;
} }
template<typename T> int amsarray<T>::resize(amsarray_size_t _newlen) template<typename T> const amsarray_size_t amsarray<T>::capacity() const
{
return this->reserved;
}
template<typename T> int amsarray<T>::reserve(amsarray_size_t _newcap)
{ {
int ret = amsarray_success; int ret = amsarray_success;
T *newdata = NULL; T *newdata = NULL;
amsarray_size_t lmin; amsarray_size_t lmin;
T defval = T(); T defval = T();
if(_newlen<=0) if(_newcap<=0)
{ {
length = 0; length = 0;
reserved = 0;
if(data!=NULL) {delete[] data; data = NULL;} if(data!=NULL) {delete[] data; data = NULL;}
ret = amsarray_success; ret = amsarray_success;
return ret; return ret;
} }
newdata = new(std::nothrow) T[_newlen]; newdata = new(std::nothrow) T[_newcap];
if(newdata==NULL) if(newdata==NULL)
{ {
ret = amsarray_failure; ret = amsarray_failure;
@ -47,15 +57,114 @@ namespace ams
if(data!=NULL) if(data!=NULL)
{ {
lmin = (_newlen>=length) ? length : _newlen; lmin = (_newcap>=reserved) ? length : _newcap;
ams::buffer_cast_copy<T,T>(newdata,data,lmin); ams::buffer_cast_copy<T,T>(newdata,data,lmin);
} }
ams::buffer_set<T>(newdata,length,_newlen,defval); ams::buffer_set<T>(newdata,reserved,_newcap,defval);
if(data!=NULL) {delete[] data; data = NULL;} if(data!=NULL) {delete[] data; data = NULL;}
data = newdata; data = newdata;
reserved = _newcap;
length = (length<reserved)? reserved : length;
return ret;
}
template<typename T> int amsarray<T>::resize(amsarray_size_t _newlen)
{
int ret = amsarray_success;
int res;
_newlen = (_newlen<0)? 0:_newlen;
res = this->reserve(_newlen);
if(res!=amsarray_success)
{
ret = amsarray_failure;
return ret;
}
length = _newlen;
ret = amsarray_success;
return ret;
}
//resizing routine for insertions/erasures,
//adjusts reserved capacity according to the growth factor
template<typename T> int amsarray<T>::resize_insert(amsarray_size_t _newlen)
{
int ret = amsarray_success;
int res;
amsarray_size_t q;
if(_newlen<=0)
{
res = this->reserve(0);
if(res!=amsarray_success)
{
ret = amsarray_failure;
return ret;
}
length = 0;
return ret;
}
if(growfactor>1.0)
{
if(_newlen>reserved)
{
q = (amsarray_size_t)(growfactor*(double)_newlen);
q = (q<_newlen) ? _newlen : q;
res = this->reserve(q);
if(res!=amsarray_success)
{
ret = amsarray_failure;
return ret;
}
length = _newlen;
return ret;
}
q = (amsarray_size_t)((1.0/growfactor)*(double)_newlen);
if(_newlen<q)
{
res = this->reserve(_newlen);
if(res!=amsarray_success)
{
ret = amsarray_failure;
return ret;
}
length = _newlen;
return ret;
}
//else do nothing
length = _newlen;
return ret;
}
else
{
//ignore growfactor
res = this->reserve(_newlen);
if(res!=amsarray_success)
{
ret = amsarray_failure;
return ret;
}
length = _newlen;
return ret;
}
//technically you shouldn't ever reach here
length = _newlen; length = _newlen;
return ret;
}
template<typename T> int amsarray<T>::shrink_to_fit()
{
int ret;
ret = this->reserve(this->length);
return ret; return ret;
} }
@ -63,6 +172,8 @@ namespace ams
{ {
int res = amsarray_success; int res = amsarray_success;
length = 0; length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL; data = NULL;
if(this!=&other) if(this!=&other)
{ {
@ -78,6 +189,8 @@ namespace ams
template<typename T> amsarray<T>::amsarray(amsarray<T>&& other) noexcept template<typename T> amsarray<T>::amsarray(amsarray<T>&& other) noexcept
{ {
length = 0; length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL; data = NULL;
if(this!=&other) if(this!=&other)
{ {
@ -110,6 +223,8 @@ namespace ams
{ {
if(data!=NULL) {delete[] data; data = NULL;} if(data!=NULL) {delete[] data; data = NULL;}
length = other.length; length = other.length;
reserved = other.reserved;
growfactor = other.growfactor;
data = other.data; data = other.data;
other.length = 0; other.length = 0;
other.data = NULL; other.data = NULL;
@ -143,6 +258,8 @@ namespace ams
amsarray_size_t I; amsarray_size_t I;
int res; int res;
length = 0; length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL; data = NULL;
res = this->resize(initlist.size()); res = this->resize(initlist.size());
@ -288,7 +405,7 @@ template<typename T> int amsarray<T>::insert(amsarray_size_t ind, const T& val)
} }
else if(ind<=this->length) else if(ind<=this->length)
{ {
res = narr.resize(this->length+1); res = narr.resize_insert(this->length+1);
if(res!=amsarray_success) if(res!=amsarray_success)
{ {
ret = amsarray_failure; ret = amsarray_failure;
@ -321,7 +438,7 @@ template<typename T> int amsarray<T>::insert(amsarray_size_t ind, const T& val)
else else
{ {
//inserting past the end of the array //inserting past the end of the array
res = narr.resize(ind+1); res = narr.resize_insert(ind+1);
if(res!=amsarray_success) if(res!=amsarray_success)
{ {
ret = amsarray_failure; ret = amsarray_failure;
@ -362,7 +479,7 @@ template<typename T> int amsarray<T>::erase(amsarray_size_t ind)
return ret; return ret;
} }
res = narr.resize(this->length-1); res = narr.resize_insert(this->length-1);
if(res!=amsarray_success) if(res!=amsarray_success)
{ {
ret = amsarray_failure; ret = amsarray_failure;
@ -735,11 +852,20 @@ template<typename T> amsarray<T> amsarray<T>::reverse()
return ret; return ret;
} }
// If I implement this generic method, then things fail to find the
// template specialized methods
template<typename T> void amsarray<T>::print(bool newline, int printstyle) template<typename T> void amsarray<T>::print(bool newline, int printstyle)
{ {
//empty method - specialize for each type //empty method - specialize for each type
return;
} }
//adding these declarations also seems to fix it.
template<> void amsarray<int>::print(bool newline, int printstyle);
template<> void amsarray<long>::print(bool newline, int printstyle);
template<> void amsarray<float>::print(bool newline, int printstyle);
template<> void amsarray<double>::print(bool newline, int printstyle);
}; //end namespace ams }; //end namespace ams

@ -189,6 +189,63 @@ void test_amsarray_sort1()
} }
void test_amsarray_insertdelete1()
{
amsarray<int> q;
int I,J,K;
q.insert(0,1);
q.print(); printf("\n");
q.insert(0,2);
q.print(); printf("\n");
q.insert(0,3);
q.print(); printf("\n");
q.insert(-1,1);
q.print(); printf("\n");
q.insert(10,99);
q.print(); printf("\n");
I = 3;
printf("q.find(%d)=%d\n",I,(int)q.find(I));
I = 1;
printf("q.find(%d)=%d\n",I,(int)q.find(I));
I = 5;
printf("q.find(%d)=%d\n",I,(int)q.find(I));
I = 99;
printf("q.find(%d)=%d\n",I,(int)q.find(I));
I = 1;
printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
I = -1;
printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
I = 5;
printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
I = 99;
printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
I = 100;
printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
q.erase(0);
q.print(); printf("\n");
q.erase(-1);
q.print(); printf("\n");
q.erase(q.length);
q.print(); printf("\n");
q.erase(q.length-1);
q.print(); printf("\n");
q.resize(0);
for(I=0;I<25;I++)
{
J = ams::rand::randint(5,25);
K = q.find_insert_ordered(J);
q.insert(K,J);
q.print(); printf("\n");
}
return;
}

@ -8,7 +8,8 @@ int main(int argc, char* argv[])
//ams::amsmathutil25::test_amsarray1(); //ams::amsmathutil25::test_amsarray1();
//ams::amsmathutil25::test_amsarray2(); //ams::amsmathutil25::test_amsarray2();
//ams::amsmathutil25::test_amsarray_select(); //ams::amsmathutil25::test_amsarray_select();
ams::amsmathutil25::test_amsarray_sort1(); //ams::amsmathutil25::test_amsarray_sort1();
ams::amsmathutil25::test_amsarray_insertdelete1();
return ret; return ret;
} }
Loading…
Cancel
Save