diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h new file mode 100644 index 000000000..333ca10ab --- /dev/null +++ b/BAN/include/BAN/Vector.h @@ -0,0 +1,169 @@ +#pragma + +#include +#include + +#include +#include +#include + +namespace BAN +{ + + template + class Vector + { + public: + using size_type = size_t; + using value_type = T; + + public: + Vector() = default; + ~Vector(); + + ErrorOr PushBack(const T&); + ErrorOr Insert(const T&, size_type); + + void PopBack(); + void Remove(size_type); + + const T& operator[](size_type) const; + T& operator[](size_type); + + ErrorOr Resize(size_type); + ErrorOr Reserve(size_type); + + bool Empty() const; + size_type Size() const; + size_type Capasity() const; + + private: + ErrorOr EnsureCapasity(size_type); + + private: + T* m_data = nullptr; + size_type m_capasity = 0; + size_type m_size = 0; + }; + + template + Vector::~Vector() + { + for (size_type i = 0; i < m_size; i++) + m_data[i].~T(); + BAN::deallocator(m_data); + } + + template + ErrorOr Vector::PushBack(const T& value) + { + TRY(EnsureCapasity(m_size + 1)); + m_data[m_size] = value; + m_size++; + return {}; + } + + template + ErrorOr Vector::Insert(const T& value, size_type index) + { + assert(index <= m_size); + TRY(EnsureCapasity(m_size + 1)); + memmove(m_data + index + 1, m_data + index, (m_size - index) * sizeof(T)); + m_data[index] = value; + m_size++; + return {}; + } + + template + void Vector::PopBack() + { + assert(m_size > 0); + m_data[m_size - 1].~T(); + m_size--; + } + + template + void Vector::Remove(size_type index) + { + assert(index < m_size); + m_data[index].~T(); + memmove(m_data + index, m_data + index + 1, (m_size - index - 1) * sizeof(T)); + m_size--; + } + + template + const T& Vector::operator[](size_type index) const + { + assert(index < m_size); + return m_data[index]; + } + + template + T& Vector::operator[](size_type index) + { + assert(index < m_size); + return m_data[index]; + } + + template + ErrorOr Vector::Resize(size_type size) + { + if (size < m_size) + { + for (size_type i = size; i < m_size; i++) + m_data[i].~T(); + m_size = size; + } + else if (size > m_size) + { + TRY(EnsureCapasity(size)); + for (size_type i = m_size; i < size; i++) + m_data[i] = T(); + m_size = size; + } + m_size = size; + return {}; + } + + template + ErrorOr Vector::Reserve(size_type size) + { + TRY(EnsureCapasity(size)); + return {}; + } + + template + bool Vector::Empty() const + { + return m_size == 0; + } + + template + typename Vector::size_type Vector::Size() const + { + return m_size; + } + + template + typename Vector::size_type Vector::Capasity() const + { + return m_capasity; + } + + template + ErrorOr Vector::EnsureCapasity(size_type size) + { + if (m_capasity >= size) + return {}; + size_type new_cap = MAX(size, m_capasity * 1.5f); + void* new_data = BAN::allocator(new_cap * sizeof(T)); + if (new_data == nullptr) + return Error::FromString("Vector: Could not allocate memory"); + memcpy(new_data, m_data, m_size * sizeof(T)); + BAN::deallocator(m_data); + m_data = (T*)new_data; + m_capasity = new_cap; + return {}; + } + +} \ No newline at end of file