add util::stack_vector

This commit is contained in:
MihailRis 2025-06-01 17:15:12 +03:00
parent 019c93d524
commit 8f342fe429

99
src/util/stack_vector.hpp Normal file
View File

@ -0,0 +1,99 @@
#pragma once
namespace util {
template<typename T, int capacity>
class stack_vector {
public:
stack_vector() : size_(0) {}
stack_vector(const stack_vector<T, capacity>& other)
: size_(other.size_) {
for (int i = 0; i < size_; ++i) {
new (&data_[i]) T(data_[i]);
}
}
stack_vector(stack_vector<T, capacity>&& other) noexcept
: size_(other.size_) {
for (int i = 0; i < size_; ++i) {
new (&data_[i]) T(std::move(other.data_[i]));
}
other.size_ = 0;
}
stack_vector(const std::initializer_list<T>& init) : size_(0) {
static_assert(
init.size() <= capacity,
"initializer list exceeds stack vector capacity"
);
for (const auto& value : init) {
new (&data_[size_++]) T(value);
}
}
~stack_vector() {
clear();
}
void push_back(const T& value) {
if (size_ < capacity) {
data_[size_++] = value;
} else {
throw std::overflow_error("stack vector capacity exceeded");
}
}
void pop_back() {
if (size_ > 0) {
data_[size_ - 1].~T();
--size_;
} else {
throw std::underflow_error("stack vector is empty");
}
}
void clear() {
for (int i = 0; i < size_; ++i) {
data_[i].~T();
}
size_ = 0;
}
T& operator[](int index) {
return data_[index];
}
const T& operator[](int index) const {
return data_[index];
}
T& at(int index) {
if (index < 0 || index >= size_) {
throw std::out_of_range("index out of range");
}
return data_[index];
}
const T& at(int index) const {
if (index < 0 || index >= size_) {
throw std::out_of_range("index out of range");
}
return data_[index];
}
int size() const {
return size_;
}
bool empty() const {
return size_ == 0;
}
bool full() const {
return size_ == capacity;
}
private:
T data_[capacity];
int size_;
};
}