Luna/libluna/include/luna/Vector.h

174 lines
3.1 KiB
C
Raw Normal View History

2023-01-13 21:28:03 +00:00
#pragma once
#include <luna/Alloc.h>
#include <luna/CString.h>
#include <luna/Result.h>
#include <luna/Types.h>
template <typename T> class Vector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;
Vector()
{
}
Vector(const Vector<T>& other)
{
reserve(other.capacity());
memcpy(m_data, other.data(), other.size());
m_size = other.size();
}
Vector(Vector<T>&& other)
{
m_data = other.data();
m_capacity = other.capacity();
m_size = other.size();
other.m_capacity = other.m_size = 0;
other.m_data = nullptr;
}
Vector<T>& operator=(const Vector<T>& other)
{
if (&other == this) return *this;
if (m_data) free_impl(m_data);
m_data = nullptr;
m_capacity = m_size = 0;
reserve(other.capacity());
memcpy(m_data, other.data(), other.size());
m_size = other.size();
return *this;
}
Vector<T>& operator=(Vector<T>&& other)
{
if (&other == this) return *this;
if (m_data) free_impl(m_data);
m_data = other.data();
m_capacity = other.capacity();
m_size = other.size();
other.m_capacity = other.m_size = 0;
other.m_data = nullptr;
return *this;
}
~Vector()
{
if (m_data) free_impl(m_data);
}
2023-01-13 21:28:03 +00:00
Result<void> try_reserve(usize capacity)
{
return resize(capacity);
}
void reserve(usize capacity)
{
resize(capacity).release_value();
}
Result<void> try_append(T&& item)
2023-01-13 21:28:03 +00:00
{
if (m_capacity == m_size) TRY(resize(m_capacity + 8));
new (&m_data[m_size]) T(move(item));
m_size++;
return {};
}
Result<void> try_append(const T& item)
{
return try_append(T(item));
}
2023-01-13 21:28:03 +00:00
Option<T> try_pop()
{
if (m_size == 0) return {};
m_size--;
return move(m_data[m_size]);
}
const T& operator[](usize index) const
{
check(index < m_size);
return m_data[m_size];
}
T& operator[](usize index)
{
check(index < m_size);
return m_data[m_size];
}
Iterator begin()
{
return m_data;
}
ConstIterator begin() const
{
return m_data;
}
Iterator end()
{
return m_data + m_size;
}
ConstIterator end() const
{
return m_data + m_size;
}
const T* data() const
{
return m_data;
}
T* data()
{
return m_data;
}
usize capacity() const
{
return m_capacity;
}
usize size() const
{
return m_size;
}
private:
T* m_data { nullptr };
usize m_capacity { 0 };
usize m_size { 0 };
Result<void> resize(usize new_capacity)
{
void* ptr = TRY(realloc_impl(m_data, new_capacity));
if (new_capacity < m_capacity) memcpy(ptr, m_data, new_capacity);
else
memcpy(ptr, m_data, m_capacity);
m_capacity = new_capacity;
m_data = (T*)ptr;
return {};
}
};