Files
CPP-Stack/include/stack.h

153 lines
3.0 KiB
C
Raw Normal View History

2026-03-15 20:31:36 -06:00
#ifndef STACK_H
#define STACK_H
2026-03-15 20:57:13 -06:00
#include <cstdint>
#include <expected>
2026-03-15 21:26:09 -06:00
#include <format>
2026-03-15 21:09:23 -06:00
#include <new>
2026-03-15 21:37:15 -06:00
#include <print>
2026-03-15 20:57:13 -06:00
#define DEFAULT_STACK_SIZE 4
enum class StackErr {
ok,
bad_alloc,
empty,
};
template<typename T>
2026-03-15 21:26:09 -06:00
requires std::formattable<T, char>
2026-03-15 20:31:36 -06:00
class Stack {
2026-03-15 20:57:13 -06:00
private:
uint64_t len;
uint64_t cap;
T *data;
public:
Stack();
~Stack();
std::expected<T, StackErr> pop();
2026-03-15 20:31:36 -06:00
2026-03-15 20:57:13 -06:00
std::expected<T, StackErr> peek();
StackErr push(T val);
uint64_t size();
2026-03-15 20:57:13 -06:00
void print();
2026-03-15 20:31:36 -06:00
};
template <typename T>
requires std::formattable<T, char>
uint64_t Stack<T>::size() {
return this->len;
}
2026-03-15 20:57:13 -06:00
template <typename T>
2026-03-15 21:26:09 -06:00
requires std::formattable<T, char>
2026-03-15 20:57:13 -06:00
Stack<T>::Stack() {
this->data = new T[DEFAULT_STACK_SIZE];
this->cap = DEFAULT_STACK_SIZE;
this->len = 0;
2026-03-15 20:57:13 -06:00
}
template <typename T>
2026-03-15 21:26:09 -06:00
requires std::formattable<T, char>
2026-03-15 20:57:13 -06:00
Stack<T>::~Stack() {
delete[] this->data;
}
2026-03-15 21:09:23 -06:00
template <typename T>
2026-03-15 21:26:09 -06:00
requires std::formattable<T, char>
2026-03-15 21:09:23 -06:00
StackErr Stack<T>::push(T value) {
// If not enough space allocate more space
if (this->len >= this->cap) {
uint64_t new_capacity = this->cap * 2;
T *tmp;
try {
tmp = new T[new_capacity];
} catch (const std::bad_alloc& e) {
return StackErr::bad_alloc;
}
for (int i = 0; i < this->len; i++) {
tmp[i] = this->data[i];
}
2026-03-15 20:57:13 -06:00
2026-03-15 21:09:23 -06:00
delete[] this->data;
this->data = tmp;
2026-03-15 21:37:15 -06:00
this->cap = new_capacity;
2026-03-15 21:09:23 -06:00
}
this->data[this->len] = value;
this->len++;
return StackErr::ok;
}
2026-03-15 20:57:13 -06:00
2026-03-15 21:26:09 -06:00
template <typename T>
requires std::formattable<T, char>
std::expected<T, StackErr> Stack<T>::pop() {
if (this->len == 0) {
return std::unexpected(StackErr::empty);
}
T return_val = this->data[this->len - 1];
this->len--;
2026-03-15 21:26:09 -06:00
if (this->cap / 4 > this->len) {
uint64_t new_capacity = this->cap / 2;
T *tmp;
try {
tmp = new T[new_capacity];
} catch (const std::bad_alloc& e) {
return std::unexpected(StackErr::bad_alloc);
}
for (int i = 0; i < this->len; i++) {
tmp[i] = this->data[i];
}
delete[] this->data;
this->data = tmp;
2026-03-15 21:37:15 -06:00
this->cap = new_capacity;
2026-03-15 21:26:09 -06:00
}
return return_val;
2026-03-15 21:26:09 -06:00
}
2026-03-15 21:28:17 -06:00
template <typename T>
requires std::formattable<T, char>
std::expected<T, StackErr> Stack<T>::peek() {
if (this->len == 0) {
return std::unexpected(StackErr::empty);
}
return this->data[this->len - 1];
2026-03-15 21:28:17 -06:00
}
2026-03-15 21:37:15 -06:00
template <typename T>
requires std::formattable<T, char>
void Stack<T>::print() {
std::println("Stack:");
std::println("Length: {}.", this->len);
std::println("Capacity: {}.", this->cap);
std::println("{:^22}", "Datos");
std::println("{:^22}", "|");
std::println("{:^22}", "v");
2026-03-15 21:37:15 -06:00
for (uint64_t i = 0; i < this->cap; i++) {
2026-03-15 21:37:15 -06:00
if (i < this->len) {
std::println("[{:^20}]", this->data[i]);
2026-03-15 21:37:15 -06:00
} else {
std::println("[{:^20}]", "EMPTY");
2026-03-15 21:37:15 -06:00
}
}
}
2026-03-15 20:31:36 -06:00
#endif // !ST