Made some of the if statements constexpr to dodge compiler errors for non-copyable or non-movable objects

This commit is contained in:
2025-07-07 22:43:13 +10:00
parent 1668d74934
commit ab95363f51

View File

@@ -60,6 +60,8 @@ namespace basalt
T& peek_front(void) noexcept;
const T& peek_front(void) const noexcept;
const bool contains(const T& val) const noexcept;
T* m_pdata = nullptr;
size_t m_nelements = 0;
size_t m_ncapacity = 0;
@@ -83,12 +85,13 @@ namespace basalt
return *this;
this->~darray();
this->m_pdata = mem::allocT<T>(src.m_nelements, src.m_tag);
BASSERT_ERROR(this->m_pdata != nullptr, return; , "Assertion %s failed at %s:%d\n\tMemory allocation failed for allocation size %u\n\t%s | %s | %u");
BASSERT_ERROR(this->m_pdata != nullptr, return *this; , "Assertion %s failed at %s:%d\n\tMemory allocation failed for allocation size %u\n\t%s | %s | %u");
this->m_tag = src.m_tag;
this->m_ncapacity = src.m_nelements;
this->m_nelements = src.m_nelements;
memcpy(this->m_pdata, src.m_pdata, sizeof(T)*this->m_nelements);
BTRACE("darray<%s> %p was copied to %p (%p)\n", typeid(T).name(), &src, this, this->m_pdata);
return *this;
}
template<typename T>
@@ -188,6 +191,9 @@ namespace basalt
{
if (this->m_pdata != nullptr)
{
if (!std::is_trivially_destructible_v<T>)
for (size_t i = 0; i < m_nelements; ++i)
m_pdata[i].~T();
mem::dealloc(this->m_pdata, this->m_ncapacity * sizeof(T), this->m_tag);
BTRACE("darray<%s> %p destroyed %p\n", typeid(T).name(), this, this->m_pdata);
}
@@ -255,7 +261,6 @@ namespace basalt
if ((this->m_nelements + new_size) > this->m_ncapacity)
this->reserve(new_size * 2);
// Call destructor for objects outside of the new size
if (!std::is_trivially_destructible_v<T>)
if (new_size < m_nelements)
for (size_t i = new_size; i < this->m_nelements; ++i)
this->m_pdata[i].~T();
@@ -268,23 +273,33 @@ namespace basalt
template<typename T>
inline void darray<T>::reserve(size_t new_capacity) noexcept
{
if (new_capacity < this->m_ncapacity)
if (new_capacity <= this->m_ncapacity)
return;
T* tmp = mem::allocT<T>(new_capacity, this->m_tag);
if (std::is_trivially_copy_assignable_v<T>)
if constexpr (std::is_trivially_copy_assignable_v<T>)
{
memcpy(tmp, this->m_pdata, this->m_nelements * sizeof(T));
else if (std::is_move_assignable_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
tmp[i] = std::move(this->m_pdata[i]);
else if (std::is_move_constructible_v<T>)
}
else if constexpr (std::is_move_constructible_v<T>)
{
for (size_t i = 0; i < this->m_nelements; ++i)
new (tmp + i) T(std::move(this->m_pdata[i]));
else if (std::is_copy_assignable_v<T>)
}
else if constexpr (std::is_move_assignable_v<T>)
{
for (size_t i = 0; i < this->m_nelements; ++i)
tmp[i] = std::move(this->m_pdata[i]);
}
else if constexpr (std::is_copy_constructible_v<T>)
{
for (size_t i = 0; i < this->m_nelements; ++i)
new (tmp + i) T(this->m_pdata[i]);
}
else if constexpr (std::is_copy_assignable_v<T>)
{
for (size_t i = 0; i < this->m_nelements; ++i)
tmp[i] = this->m_pdata[i];
else if (std::is_copy_constructible_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
new (tmp+i) T(this->m_pdata[i]);
}
else
{
BERROR("Can not resize object dynarray<%s>\n\tIt is not trivially copyable, copy assignable, copy constructible, move assignable or move constructable\n", typeid(T).name());
@@ -292,7 +307,6 @@ namespace basalt
return;
}
if (!std::is_trivially_destructible_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
this->m_pdata[i].~T();
mem::dealloc(this->m_pdata, this->m_ncapacity*sizeof(T), this->m_tag);
@@ -306,18 +320,18 @@ namespace basalt
if (this->m_nelements == this->m_ncapacity)
return;
T* tmp = mem::allocT<T>(this->m_nelements, this->m_tag);
if (std::is_trivially_copy_assignable_v<T>)
if constexpr (std::is_trivially_copy_assignable_v<T>)
memcpy(tmp, this->m_pdata, this->m_nelements * sizeof(T));
else if (std::is_move_assignable_v<T>)
else if constexpr(std::is_move_assignable_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
tmp[i] = std::move(this->m_pdata[i]);
else if (std::is_move_constructible_v<T>)
else if constexpr (std::is_move_constructible_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
new (tmp + i) T(std::move(this->m_pdata[i]));
else if (std::is_copy_assignable_v<T>)
else if constexpr (std::is_copy_assignable_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
tmp[i] = this->m_pdata[i];
else if (std::is_copy_constructible_v<T>)
else if constexpr (std::is_copy_constructible_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
new (tmp + i) T(this->m_pdata[i]);
else
@@ -327,7 +341,6 @@ namespace basalt
return;
}
if (!std::is_trivially_destructible_v<T>)
for (size_t i = 0; i < this->m_nelements; ++i)
this->m_pdata[i].~T();
mem::dealloc(this->m_pdata, this->m_ncapacity * sizeof(T), this->m_tag);
@@ -341,11 +354,11 @@ namespace basalt
{
if ((this->m_nelements + 1) > this->m_ncapacity)
this->expand(this->m_ncapacity < 1 ? 1 : this->m_ncapacity);
if (std::is_trivially_copyable_v<T>)
if constexpr (std::is_trivially_copyable_v<T>)
memcpy(this->m_pdata + this->m_nelements, &val, sizeof(T));
else if (std::is_copy_constructible_v<T>)
else if constexpr (std::is_copy_constructible_v<T>)
new (this->m_pdata + this->m_nelements) T(val);
else if (std::is_copy_assignable_v<T>)
else if constexpr (std::is_copy_assignable_v<T>)
this->m_pdata[this->m_nelements] = val;
else
{
@@ -360,11 +373,11 @@ namespace basalt
{
if ((this->m_nelements + 1) > this->m_ncapacity)
this->expand(this->m_ncapacity < 1 ? 1 : this->m_ncapacity);
if (std::is_trivially_move_assignable_v<T>)
if constexpr (std::is_trivially_move_assignable_v<T>)
memcpy(this->m_pdata + this->m_nelements, &val, sizeof(T));
else if (std::is_move_constructible_v<T>)
else if constexpr (std::is_move_constructible_v<T>)
new (this->m_pdata + this->m_nelements) T(std::move(val));
else if (std::is_move_assignable_v<T>)
else if constexpr (std::is_move_assignable_v<T>)
this->m_pdata[this->m_nelements] = std::move(val);
else
{
@@ -381,16 +394,16 @@ namespace basalt
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>)
if constexpr (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>)
else if constexpr (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>)
else if constexpr (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]);
@@ -454,7 +467,6 @@ namespace basalt
idx = 0;
darray<T> tmp = std::move(this->m_pdata[idx]);
--this->m_nelements;
if (!std::is_trivially_destructible_v<T>)
this->m_pdata[this->m_nelements].~T();
return std::move(tmp);
}