diff --git a/src/src/utils/vector.h b/src/src/utils/vector.h new file mode 100644 index 0000000..7d711db --- /dev/null +++ b/src/src/utils/vector.h @@ -0,0 +1,106 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +template +class CreateVector { + static_assert(std::is_trivially_destructible_v, "CreateVector only supports trivially destructible types for max performance."); + + T* data_ = nullptr; + size_t size_ = 0; + size_t capacity_ = 0; + + static constexpr size_t kMinCapacity = 8; + + inline void grow(size_t minCapacity) { + size_t newCap = capacity_ ? capacity_ * 2 : kMinCapacity; + if (newCap < minCapacity) newCap = minCapacity; + + T* newData = (T*)std::malloc(newCap * sizeof(T)); + if (data_) { + std::memcpy(newData, data_, size_ * sizeof(T)); + std::free(data_); + } + data_ = newData; + capacity_ = newCap; + } + +public: + inline CreateVector() = default; + + inline ~CreateVector() { + std::free(data_); + } + + inline CreateVector(const CreateVector&) = delete; + inline CreateVector& operator=(const CreateVector&) = delete; + + inline CreateVector(CreateVector&& other) noexcept + : data_(other.data_), size_(other.size_), capacity_(other.capacity_) { + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + } + + inline CreateVector& operator=(CreateVector&& other) noexcept { + if (this != &other) { + std::free(data_); + data_ = other.data_; + size_ = other.size_; + capacity_ = other.capacity_; + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + } + return *this; + } + + inline void push_back(const T& value) { + if (size_ == capacity_) grow(size_ + 1); + data_[size_++] = value; + } + + inline void push_back(T&& value) { + if (size_ == capacity_) grow(size_ + 1); + data_[size_++] = std::move(value); + } + + inline void pop_back() { + assert(size_ > 0); + --size_; + } + + inline void clear() { + size_ = 0; + } + + inline void resize(size_t newSize) { + if (newSize > capacity_) grow(newSize); + size_ = newSize; + } + + inline void reserve(size_t newCap) { + if (newCap > capacity_) grow(newCap); + } + + inline T& operator[](size_t index) { + assert(index < size_); + return data_[index]; + } + + inline const T& operator[](size_t index) const { + assert(index < size_); + return data_[index]; + } + + inline T* data() { return data_; } + inline const T* data() const { return data_; } + + inline size_t size() const { return size_; } + inline size_t capacity() const { return capacity_; } + inline bool empty() const { return size_ == 0; } +};