From cd1430d2588dd6a2505ffb18a755c153c2c56499 Mon Sep 17 00:00:00 2001 From: Riley King-Saunders Date: Tue, 24 Jun 2025 15:34:26 +1000 Subject: [PATCH] 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 --- include/containers/basalt_darray.h | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/include/containers/basalt_darray.h b/include/containers/basalt_darray.h index 5cb62a7..917c352 100644 --- a/include/containers/basalt_darray.h +++ b/include/containers/basalt_darray.h @@ -16,12 +16,15 @@ namespace basalt darray(darray&& src); darray& operator =(darray&& src); + darray(const std::initializer_list& 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& 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& src); T&& pop_back(void) noexcept; T& peek_back(void) noexcept; @@ -108,6 +114,28 @@ namespace basalt return *this; } + template + inline darray::darray(const std::initializer_list& vals, MEMORY_TAG tag) + { + this->m_pdata = mem::allocT(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) + memcpy(this->m_pdata, vals.begin(), vals.size() * sizeof(T)); + else if (std::is_copy_assignable_v) + for (size_t i = 0; i < vals.size(); ++i) + this->m_pdata[i] = *(vals.begin() + i); + else if (std::is_copy_constructible_v) + 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 inline darray::darray(MEMORY_TAG tag) { @@ -121,6 +149,8 @@ namespace basalt inline darray::darray(size_t n_capacity, MEMORY_TAG tag) { this->m_pdata = mem::allocT(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::darray(size_t n_elements, const T& fill_value, MEMORY_TAG tag) { this->m_pdata = mem::allocT(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 + inline void darray::changetag(MEMORY_TAG new_tag) + { + basalt::mem::changetag(sizeof(T) * this->m_ncapacity, this->m_tag, new_tag); + this->m_tag = new_tag; + } template const size_t darray::size(void) const noexcept { return m_nelements; } @@ -316,6 +354,43 @@ namespace basalt this->m_nelements++; } + template + inline void darray::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) + { + memcpy(this->m_pdata + this->m_nelements, beg, sizeof(T) * nelements); + } + else if (std::is_copy_assignable_v) + { + for (size_t i = 0; i < nelements; ++i) + this->m_pdata[this->m_nelements + i] = beg[i]; + } + else if (std::is_copy_constructible_v) + { + 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 + inline void darray::push_back(T* base, const size_t nelements) + { this->push_back(base, base+nelements); } + + template + inline void darray::push_back(const darray& src) + { this->push_back(src.m_pdata, src.m_pdata+src.m_nelements); } + template inline const T& darray::peek_back(void) const noexcept {