array growth/shrinkage/reserve system

This commit is contained in:
2025-06-02 20:53:01 -04:00
parent 9321846172
commit 0db503a9f5
23 changed files with 208 additions and 11 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -13,6 +13,9 @@ namespace ams
{
public:
amsarray_size_t length;
amsarray_size_t reserved;
double growfactor;
T *data;
//Rule of 5 boilerplate
@ -37,8 +40,17 @@ namespace ams
// amsarray_failure.
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
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);
const T& operator[](amsarray_size_t ind) const;

View File

@ -7,6 +7,8 @@ namespace ams
template<typename T> amsarray<T>::amsarray()
{
length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL;
return;
}
@ -14,6 +16,8 @@ namespace ams
template<typename T> amsarray<T>::~amsarray()
{
length = 0;
reserved = 0;
growfactor = 1.5;
if(data!=NULL) {delete[] data; data = NULL;}
return;
}
@ -23,22 +27,28 @@ namespace ams
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;
T *newdata = NULL;
amsarray_size_t lmin;
T defval = T();
if(_newlen<=0)
if(_newcap<=0)
{
length = 0;
reserved = 0;
if(data!=NULL) {delete[] data; data = NULL;}
ret = amsarray_success;
return ret;
}
newdata = new(std::nothrow) T[_newlen];
newdata = new(std::nothrow) T[_newcap];
if(newdata==NULL)
{
ret = amsarray_failure;
@ -47,22 +57,123 @@ namespace ams
if(data!=NULL)
{
lmin = (_newlen>=length) ? length : _newlen;
lmin = (_newcap>=reserved) ? length : _newcap;
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;}
data = newdata;
length = _newlen;
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;
return ret;
}
template<typename T> int amsarray<T>::shrink_to_fit()
{
int ret;
ret = this->reserve(this->length);
return ret;
}
template<typename T> amsarray<T>::amsarray(const amsarray<T>& other)
{
int res = amsarray_success;
length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL;
if(this!=&other)
{
@ -78,6 +189,8 @@ namespace ams
template<typename T> amsarray<T>::amsarray(amsarray<T>&& other) noexcept
{
length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL;
if(this!=&other)
{
@ -110,6 +223,8 @@ namespace ams
{
if(data!=NULL) {delete[] data; data = NULL;}
length = other.length;
reserved = other.reserved;
growfactor = other.growfactor;
data = other.data;
other.length = 0;
other.data = NULL;
@ -143,6 +258,8 @@ namespace ams
amsarray_size_t I;
int res;
length = 0;
reserved = 0;
growfactor = 1.5;
data = NULL;
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)
{
res = narr.resize(this->length+1);
res = narr.resize_insert(this->length+1);
if(res!=amsarray_success)
{
ret = amsarray_failure;
@ -321,7 +438,7 @@ template<typename T> int amsarray<T>::insert(amsarray_size_t ind, const T& val)
else
{
//inserting past the end of the array
res = narr.resize(ind+1);
res = narr.resize_insert(ind+1);
if(res!=amsarray_success)
{
ret = amsarray_failure;
@ -362,7 +479,7 @@ template<typename T> int amsarray<T>::erase(amsarray_size_t ind)
return ret;
}
res = narr.resize(this->length-1);
res = narr.resize_insert(this->length-1);
if(res!=amsarray_success)
{
ret = amsarray_failure;
@ -735,11 +852,20 @@ template<typename T> amsarray<T> amsarray<T>::reverse()
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)
{
//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

View File

@ -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;
}

View File

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