BAN: Add reallocator and make Vector use it

This commit is contained in:
Oskari Alaranta 2026-02-21 03:54:08 +02:00
parent 778af77654
commit 88ccba3dee
2 changed files with 38 additions and 9 deletions

View File

@ -10,9 +10,11 @@ namespace BAN
{ {
#if defined(__is_kernel) #if defined(__is_kernel)
static constexpr void*(&allocator)(size_t) = kmalloc; static constexpr void*(&allocator)(size_t) = kmalloc;
static constexpr void*(&reallocator)(void*, size_t) = nullptr;
static constexpr void(&deallocator)(void*) = kfree; static constexpr void(&deallocator)(void*) = kfree;
#else #else
static constexpr void*(&allocator)(size_t) = malloc; static constexpr void*(&allocator)(size_t) = malloc;
static constexpr void*(&reallocator)(void*, size_t) = realloc;
static constexpr void(&deallocator)(void*) = free; static constexpr void(&deallocator)(void*) = free;
#endif #endif
} }

View File

@ -381,19 +381,46 @@ namespace BAN
template<typename T> template<typename T>
ErrorOr<void> Vector<T>::ensure_capacity(size_type size) ErrorOr<void> Vector<T>::ensure_capacity(size_type size)
{ {
static_assert(alignof(T) <= alignof(max_align_t), "over aligned types not supported");
if (m_capacity >= size) if (m_capacity >= size)
return {}; return {};
size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2);
T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); const size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2);
if (new_data == nullptr)
return Error::from_errno(ENOMEM); if constexpr (BAN::is_trivially_copyable_v<T>)
for (size_type i = 0; i < m_size; i++)
{ {
new (new_data + i) T(move(m_data[i])); if constexpr (BAN::reallocator)
m_data[i].~T(); {
auto* new_data = static_cast<T*>(BAN::reallocator(m_data, new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
m_data = new_data;
}
else
{
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
memcpy(new_data, m_data, m_size * sizeof(T));
BAN::deallocator(m_data);
m_data = new_data;
}
} }
BAN::deallocator(m_data); else
m_data = new_data; {
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
for (size_type i = 0; i < m_size; i++)
{
new (new_data + i) T(move(m_data[i]));
m_data[i].~T();
}
BAN::deallocator(m_data);
m_data = new_data;
}
m_capacity = new_cap; m_capacity = new_cap;
return {}; return {};
} }