Added initializer list constructor

Added array push back functions for iterator-style, base-length style and other darrays
Added check to constructors to ensure that allocation of the memory succeeded before setting values
Added changetag function and a default tag for initializer list constructor
This commit is contained in:
2025-06-24 15:34:26 +10:00
parent 6f1373f223
commit cd1430d258

View File

@@ -16,12 +16,15 @@ namespace basalt
darray(darray<T>&& src);
darray<T>& operator =(darray<T>&& src);
darray(const std::initializer_list<T>& vals,
MEMORY_TAG tag=MEMORY_TAG_CLASS_DYNARRAY | MEMORY_TAG_ZONE_UNKNOWN | MEMORY_TAG_ALIGN_ANY);
darray(MEMORY_TAG tag);
darray(size_t n_capacity, MEMORY_TAG tag);
darray(size_t n_elements, const T& fill_value, MEMORY_TAG tag);
~darray();
void swap(darray<T>& other);
void changetag(MEMORY_TAG new_tag);
T* operator +(const size_t offset) noexcept;
T* operator -(const size_t offset) noexcept;
@@ -42,6 +45,9 @@ namespace basalt
void push_back(const T& val) noexcept;
void push_back(T&& val) noexcept;
void push_back(T* beg, T* end);
void push_back(T* base, size_t nelements);
void push_back(const darray<T>& src);
T&& pop_back(void) noexcept;
T& peek_back(void) noexcept;
@@ -108,6 +114,28 @@ namespace basalt
return *this;
}
template<typename T>
inline darray<T>::darray(const std::initializer_list<T>& vals, MEMORY_TAG tag)
{
this->m_pdata = mem::allocT<T>(vals.size(), tag);
if (this->m_pdata == nullptr)
return;
this->m_ncapacity = vals.size();
this->m_nelements = vals.size();
this->m_tag = tag;
if (std::is_trivially_copyable_v<T>)
memcpy(this->m_pdata, vals.begin(), vals.size() * sizeof(T));
else if (std::is_copy_assignable_v<T>)
for (size_t i = 0; i < vals.size(); ++i)
this->m_pdata[i] = *(vals.begin() + i);
else if (std::is_copy_constructible_v<T>)
for (size_t i = 0; i < vals.size(); ++i)
new (this->m_pdata + i) T(*(vals.begin() + i));
else BASSERT_FATAL(false, "Assertion %s failed at %s:%d\n\tFailed to copy objects from initializer_list<%s> into darray<%s>\n\t\t%s was not copyable\n",
typeid(T).name(), typeid(T).name(), typeid(T).name());
}
template<typename T>
inline darray<T>::darray(MEMORY_TAG tag)
{
@@ -121,6 +149,8 @@ namespace basalt
inline darray<T>::darray(size_t n_capacity, MEMORY_TAG tag)
{
this->m_pdata = mem::allocT<T>(n_capacity, tag);
if (this->m_pdata == nullptr)
return;
this->m_ncapacity = n_capacity;
this->m_nelements = 0;
this->m_tag = tag;
@@ -130,6 +160,8 @@ namespace basalt
inline darray<T>::darray(size_t n_elements, const T& fill_value, MEMORY_TAG tag)
{
this->m_pdata = mem::allocT<T>(n_capacity, tag);
if (this->m_pdata == nullptr)
return;
this->m_ncapacity = n_capacity;
this->m_nelements = n_elements;
for (size_t i = 0; i < n_elements; ++i)
@@ -162,6 +194,12 @@ namespace basalt
other.m_pdata = this->m_pdata;
this->m_pdata = tmp;
}
template<typename T>
inline void darray<T>::changetag(MEMORY_TAG new_tag)
{
basalt::mem::changetag(sizeof(T) * this->m_ncapacity, this->m_tag, new_tag);
this->m_tag = new_tag;
}
template <typename T>
const size_t darray<T>::size(void) const noexcept
{ return m_nelements; }
@@ -316,6 +354,43 @@ namespace basalt
this->m_nelements++;
}
template<typename T>
inline void darray<T>::push_back(T* beg, T* end)
{
ptrdiff_t nelements = end - beg;
nelements = nelements < 0 ? -nelements : nelements;
if ((this->m_nelements + nelements) > this->m_ncapacity)
this->expand(nelements + this->m_nelements + 1);
if (std::is_trivially_copyable_v<T>)
{
memcpy(this->m_pdata + this->m_nelements, beg, sizeof(T) * nelements);
}
else if (std::is_copy_assignable_v<T>)
{
for (size_t i = 0; i < nelements; ++i)
this->m_pdata[this->m_nelements + i] = beg[i];
}
else if (std::is_copy_constructible_v<T>)
{
for (size_t i = 0; i < nelements; ++i)
new (this->m_pdata + this->m_nelements + i) T(beg[i]);
}
else
{
BERROR("Can not use push_back(const %s&) on object that is not copy constructable or assignable\n", typeid(T).name());
return;
}
this->m_nelements += nelements;
}
template<typename T>
inline void darray<T>::push_back(T* base, const size_t nelements)
{ this->push_back(base, base+nelements); }
template<typename T>
inline void darray<T>::push_back(const darray<T>& src)
{ this->push_back(src.m_pdata, src.m_pdata+src.m_nelements); }
template<typename T>
inline const T& darray<T>::peek_back(void) const noexcept
{