#pragma once #include #include namespace glcr { template class Vector { public: Vector() : data_(nullptr), size_(0), capacity_(0) {} Vector(const Vector&) = delete; // TODO: Implement Move Vector(Vector&&) = delete; ~Vector() { delete[] data_; } // FIXME: Handle downsizing. void Resize(uint64_t capacity); // Setters. void PushBack(const T& item); void PushBack(T&& item); template void EmplaceBack(Args... args); // Accessors. T& operator[](uint64_t index); const T& operator[](uint64_t index) const; T& at(uint64_t index); const T& at(uint64_t index) const; uint64_t size() const { return size_; } uint64_t capacity() const { return capacity_; } private: T* data_; uint64_t size_; uint64_t capacity_; void Expand(); }; template void Vector::Resize(uint64_t capacity) { T* new_data = reinterpret_cast(new uint8_t[capacity * sizeof(T)]); for (uint64_t i = 0; i < size_; i++) { new_data[i] = glcr::Move(data_[i]); } delete[] data_; data_ = new_data; capacity_ = capacity; } template void Vector::PushBack(const T& item) { if (size_ >= capacity_) { Expand(); } data_[size_++] = item; } template void Vector::PushBack(T&& item) { if (size_ >= capacity_) { Expand(); } data_[size_++] = glcr::Move(item); } template template void Vector::EmplaceBack(Args... args) { if (size_ >= capacity_) { Expand(); } data_[size_++] = T(args...); } template T& Vector::operator[](uint64_t index) { return data_[index]; } template const T& Vector::operator[](uint64_t index) const { return data_[index]; } template T& Vector::at(uint64_t index) { return data_[index]; } template const T& Vector::at(uint64_t index) const { return data_[index]; } template void Vector::Expand() { uint64_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2; Resize(new_capacity); } } // namespace glcr