comments, al .md done

This commit is contained in:
2026-03-17 22:35:35 -06:00
parent f3dc4ce7c5
commit a2a395ce66

View File

@@ -7,35 +7,76 @@
#include <format> #include <format>
#include <expected> #include <expected>
/// @brief Default initial capacity for the queue
#define DEFAULT_QUEUE_SIZE 4 #define DEFAULT_QUEUE_SIZE 4
/**
* @enum QueueErr
* @brief Represents possible error states for queue operations
*/
enum class QueueErr { enum class QueueErr {
ok, ok, ///< Operation successful
bad_alloc, bad_alloc, ///< Memory allocation failed
empty, empty, ///< Queue is empty
}; };
/**
* @class Queue
* @brief A dynamically resizing circular queue implementation
*
* @tparam T Type of elements stored in the queue. Must be formattable.
*/
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
class Queue { class Queue {
private: private:
uint64_t len; uint64_t len; ///< Current number of elements
uint64_t cap; uint64_t cap; ///< Current capacity
uint64_t head; uint64_t head; ///< Index of next insertion
uint64_t tail; uint64_t tail; ///< Index of next removal
T *data; T *data; ///< Pointer to dynamically allocated array
public: public:
/**
* @brief Default constructor
* Initializes the queue with DEFAULT_QUEUE_SIZE capacity
*/
Queue(); Queue();
/**
* @brief Constructor with custom size
* @param size Initial capacity of the queue
*/
Queue(uint64_t size); Queue(uint64_t size);
/**
* @brief Destructor
* Frees allocated memory
*/
~Queue(); ~Queue();
/**
* @brief Inserts an element at the end of the queue
* @param value Value to insert
* @return QueueErr Status of the operation
*/
QueueErr enqueue(T value); QueueErr enqueue(T value);
/**
* @brief Returns the front element without removing it
* @return std::expected<T, QueueErr> Value or error if empty
*/
std::expected<T, QueueErr> peek(); std::expected<T, QueueErr> peek();
/**
* @brief Removes and returns the front element
* @return std::expected<T, QueueErr> Value or error if empty
*/
std::expected<T, QueueErr> dequeue(); std::expected<T, QueueErr> dequeue();
/**
* @brief Prints a visual representation of the queue
*/
void print(); void print();
}; };
@@ -52,12 +93,11 @@ Queue<T>::Queue() {
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
Queue<T>::Queue(uint64_t size) { Queue<T>::Queue(uint64_t size) {
this->cap = DEFAULT_QUEUE_SIZE; this->cap = size;
this->len = 0; this->len = 0;
this->head = 0; this->head = 0;
this->tail = 0; this->tail = 0;
this->data = new T[size]; this->data = new T[size];
} }
template <typename T> template <typename T>
@@ -70,10 +110,10 @@ Queue<T>::~Queue() {
this->tail = 0; this->tail = 0;
} }
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
QueueErr Queue<T>::enqueue(T value) { QueueErr Queue<T>::enqueue(T value) {
/// Resize if needed
if (this->len >= this->cap) { if (this->len >= this->cap) {
uint64_t new_cap = this->cap * 2; uint64_t new_cap = this->cap * 2;
T *tmp; T *tmp;
@@ -84,6 +124,7 @@ QueueErr Queue<T>::enqueue(T value) {
return QueueErr::bad_alloc; return QueueErr::bad_alloc;
} }
/// Copy elements in correct order
for (uint64_t i = 0; i < this->len; i++) { for (uint64_t i = 0; i < this->len; i++) {
uint64_t index = (this->tail + i) % this->cap; uint64_t index = (this->tail + i) % this->cap;
tmp[i] = this->data[index]; tmp[i] = this->data[index];
@@ -99,16 +140,19 @@ QueueErr Queue<T>::enqueue(T value) {
this->data[this->head] = value; this->data[this->head] = value;
this->len++; this->len++;
this->head = (this->head + 1) % this->cap; this->head = (this->head + 1) % this->cap;
return QueueErr::ok; return QueueErr::ok;
} }
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
std::expected<T, QueueErr> Queue<T>::dequeue() { std::expected<T, QueueErr> Queue<T>::dequeue() {
/// Check if empty
if (this->len == 0) { if (this->len == 0) {
return std::unexpected(QueueErr::empty); return std::unexpected(QueueErr::empty);
} }
/// Shrink if too sparse
if (this->cap > DEFAULT_QUEUE_SIZE && this->cap / 4 > this->len) { if (this->cap > DEFAULT_QUEUE_SIZE && this->cap / 4 > this->len) {
uint64_t new_cap = this->cap / 2; uint64_t new_cap = this->cap / 2;
if (new_cap < DEFAULT_QUEUE_SIZE) { if (new_cap < DEFAULT_QUEUE_SIZE) {
@@ -122,6 +166,7 @@ std::expected<T, QueueErr> Queue<T>::dequeue() {
return std::unexpected(QueueErr::bad_alloc); return std::unexpected(QueueErr::bad_alloc);
} }
/// Copy elements
for (uint64_t i = 0; i < this->len; i++) { for (uint64_t i = 0; i < this->len; i++) {
uint64_t index = (this->tail + i) % this->cap; uint64_t index = (this->tail + i) % this->cap;
tmp[i] = this->data[index]; tmp[i] = this->data[index];
@@ -132,11 +177,10 @@ std::expected<T, QueueErr> Queue<T>::dequeue() {
this->cap = new_cap; this->cap = new_cap;
this->tail = 0; this->tail = 0;
this->head = this->len; this->head = this->len;
} }
T out; T out = this->data[this->tail];
out = this->data[this->tail];
this->len--; this->len--;
this->tail = (this->tail + 1) % this->cap; this->tail = (this->tail + 1) % this->cap;
@@ -146,18 +190,18 @@ std::expected<T, QueueErr> Queue<T>::dequeue() {
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
std::expected<T, QueueErr> Queue<T>::peek() { std::expected<T, QueueErr> Queue<T>::peek() {
/// Check if empty
if (this->len == 0) { if (this->len == 0) {
return std::unexpected(QueueErr::empty); return std::unexpected(QueueErr::empty);
} }
T out; return this->data[this->tail];
out = this->data[this->tail];
return out;
} }
template <typename T> template <typename T>
requires std::formattable<T, char> requires std::formattable<T, char>
void Queue<T>::print() { void Queue<T>::print() {
/// Print queue state
if (this->len == 0) { if (this->len == 0) {
std::println("Queue is empty."); std::println("Queue is empty.");
return; return;
@@ -186,4 +230,5 @@ void Queue<T>::print() {
} }
} }
} }
#endif // !QUEUE_H #endif // !QUEUE_H