2022-12-26 00:31:00 -05:00
|
|
|
/*
|
|
|
|
* Created by Brett on 26/12/22.
|
|
|
|
* Licensed under GNU General Public License V3.0
|
|
|
|
* See LICENSE file for license detail
|
|
|
|
*/
|
|
|
|
|
2023-01-05 12:34:14 -05:00
|
|
|
#ifndef BLT_QUEUE_H
|
|
|
|
#define BLT_QUEUE_H
|
2022-12-26 00:31:00 -05:00
|
|
|
|
2022-12-26 23:36:34 -05:00
|
|
|
/**
|
2023-03-04 22:38:25 -05:00
|
|
|
*
|
2022-12-26 23:36:34 -05:00
|
|
|
*/
|
2023-12-16 15:53:02 -05:00
|
|
|
namespace blt
|
|
|
|
{
|
2022-12-26 00:31:00 -05:00
|
|
|
|
2023-01-05 12:34:14 -05:00
|
|
|
/**
|
|
|
|
* Standard array backed first in first out queue
|
|
|
|
* @tparam T type stored in the queue
|
|
|
|
*/
|
2022-12-26 00:31:00 -05:00
|
|
|
template<typename T>
|
2023-12-16 15:53:02 -05:00
|
|
|
class flat_stack
|
|
|
|
{
|
2022-12-26 01:10:37 -05:00
|
|
|
private:
|
2023-01-05 12:10:38 -05:00
|
|
|
int m_size = 16;
|
|
|
|
int m_insertIndex = 0;
|
|
|
|
T* m_data = new T[m_size];
|
2022-12-26 01:10:37 -05:00
|
|
|
|
2023-01-04 14:35:57 -05:00
|
|
|
/**
|
|
|
|
* Expands the internal array to the new size, copying over the data and shifting its minimal position to index 0
|
|
|
|
* and deletes the old array from memory.
|
|
|
|
* @param newSize new size of the internal array
|
|
|
|
*/
|
2023-12-16 15:53:02 -05:00
|
|
|
void expand()
|
|
|
|
{
|
2023-03-04 22:38:25 -05:00
|
|
|
int new_size = m_size * 2;
|
|
|
|
auto tempData = new T[new_size];
|
2023-01-05 12:10:38 -05:00
|
|
|
for (int i = 0; i < m_insertIndex; i++)
|
|
|
|
tempData[i] = m_data[i];
|
|
|
|
delete[] m_data;
|
|
|
|
m_data = tempData;
|
2023-03-04 22:38:25 -05:00
|
|
|
m_size = new_size;
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
|
|
|
|
2023-01-05 12:10:38 -05:00
|
|
|
public:
|
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
void push(const T& t)
|
|
|
|
{
|
|
|
|
if (m_insertIndex >= m_size)
|
|
|
|
{
|
2023-03-04 22:38:25 -05:00
|
|
|
expand();
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
2023-01-05 12:10:38 -05:00
|
|
|
m_data[m_insertIndex++] = t;
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
2023-01-05 12:10:38 -05:00
|
|
|
|
2023-01-05 01:52:56 -05:00
|
|
|
/**
|
|
|
|
* Warning does not contain runtime error checking!
|
|
|
|
* @return the element at the "front" of the queue.
|
|
|
|
*/
|
2023-12-16 15:53:02 -05:00
|
|
|
[[nodiscard]] const T& top() const
|
|
|
|
{
|
2023-01-05 12:10:38 -05:00
|
|
|
return m_data[m_insertIndex - 1];
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
2023-01-05 12:10:38 -05:00
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
void pop()
|
|
|
|
{
|
2023-03-05 12:00:45 -05:00
|
|
|
if (empty())
|
2023-01-05 01:52:56 -05:00
|
|
|
return;
|
2023-01-05 12:10:38 -05:00
|
|
|
m_insertIndex--;
|
2023-01-05 01:52:56 -05:00
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
[[nodiscard]] inline bool empty() const
|
|
|
|
{
|
2023-01-05 12:10:38 -05:00
|
|
|
return m_insertIndex <= 0;
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
[[nodiscard]] inline int size() const
|
|
|
|
{
|
2023-01-05 12:10:38 -05:00
|
|
|
return m_insertIndex;
|
2023-01-05 11:49:45 -05:00
|
|
|
}
|
2023-01-05 12:10:38 -05:00
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
~flat_stack()
|
|
|
|
{
|
2023-01-05 12:10:38 -05:00
|
|
|
delete[](m_data);
|
2022-12-26 01:10:37 -05:00
|
|
|
}
|
2022-12-26 00:31:00 -05:00
|
|
|
};
|
|
|
|
|
2023-01-05 12:34:14 -05:00
|
|
|
/**
|
|
|
|
* Standard array backed first in last out queue (stack)
|
|
|
|
* @tparam T type stored in the queue
|
|
|
|
*/
|
|
|
|
template<typename T>
|
2023-12-16 15:53:02 -05:00
|
|
|
class flat_queue
|
|
|
|
{
|
2023-01-05 12:34:14 -05:00
|
|
|
private:
|
|
|
|
int m_size = 16;
|
|
|
|
int m_headIndex = 0;
|
|
|
|
int m_insertIndex = 0;
|
2023-03-04 22:38:25 -05:00
|
|
|
T* m_data;
|
2023-12-16 15:53:02 -05:00
|
|
|
|
2023-01-05 12:34:14 -05:00
|
|
|
/**
|
2023-03-04 22:38:25 -05:00
|
|
|
* Expands the internal array to allow for more storage of elements
|
2023-01-05 12:34:14 -05:00
|
|
|
*/
|
2023-12-16 15:53:02 -05:00
|
|
|
void expand()
|
|
|
|
{
|
2023-03-04 22:38:25 -05:00
|
|
|
int new_size = m_size * 2;
|
|
|
|
int removed_size = m_size - m_headIndex;
|
|
|
|
auto tempData = new T[new_size];
|
|
|
|
// only copy data from where we've removed onward
|
|
|
|
for (int i = 0; i < removed_size; i++)
|
|
|
|
tempData[i] = m_data[i + m_headIndex]; // but don't copy data we've pop'd
|
2023-01-05 12:34:14 -05:00
|
|
|
delete[] m_data;
|
|
|
|
m_headIndex = 0;
|
2023-03-04 22:38:25 -05:00
|
|
|
m_insertIndex = removed_size - 1;
|
2023-01-05 12:34:14 -05:00
|
|
|
m_data = tempData;
|
2023-03-04 22:38:25 -05:00
|
|
|
m_size = new_size;
|
2023-01-05 12:34:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2023-12-16 15:53:02 -05:00
|
|
|
flat_queue(): m_data(new T[m_size])
|
|
|
|
{
|
2023-03-04 22:38:25 -05:00
|
|
|
|
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
inline void push(const T& t)
|
|
|
|
{
|
|
|
|
if (m_insertIndex + 1 >= m_size)
|
|
|
|
{
|
2023-03-04 22:38:25 -05:00
|
|
|
expand();
|
2023-01-05 12:34:14 -05:00
|
|
|
}
|
|
|
|
m_data[m_insertIndex++] = t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Warning does not contain runtime error checking!
|
|
|
|
* @return the element at the "front" of the queue.
|
|
|
|
*/
|
2023-12-16 15:53:02 -05:00
|
|
|
[[nodiscard]] const T& front() const
|
|
|
|
{
|
2023-01-05 12:34:14 -05:00
|
|
|
return m_data[m_headIndex];
|
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
[[nodiscard]] T& front()
|
|
|
|
{
|
|
|
|
return m_data[m_headIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void pop()
|
|
|
|
{
|
2023-03-05 12:00:45 -05:00
|
|
|
if (empty())
|
2023-01-05 12:34:14 -05:00
|
|
|
return;
|
2023-01-05 12:40:08 -05:00
|
|
|
m_headIndex++;
|
2023-01-05 12:34:14 -05:00
|
|
|
}
|
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
[[nodiscard]] inline bool empty() const
|
|
|
|
{
|
2023-01-05 12:34:14 -05:00
|
|
|
return m_headIndex >= m_size;
|
|
|
|
}
|
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
[[nodiscard]] inline int size() const
|
|
|
|
{
|
2023-01-05 12:34:14 -05:00
|
|
|
return m_insertIndex - m_headIndex;
|
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
inline T* begin()
|
|
|
|
{
|
2023-01-26 00:59:36 -05:00
|
|
|
return m_data[m_headIndex];
|
|
|
|
}
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
inline T* end()
|
|
|
|
{
|
2023-01-26 00:59:36 -05:00
|
|
|
return m_data[m_insertIndex];
|
|
|
|
}
|
|
|
|
|
2023-12-16 15:53:02 -05:00
|
|
|
~flat_queue()
|
|
|
|
{
|
2023-01-05 12:34:14 -05:00
|
|
|
delete[](m_data);
|
|
|
|
}
|
|
|
|
};
|
2023-12-16 15:53:02 -05:00
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
class linked_stack
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
struct node
|
|
|
|
{
|
|
|
|
T t;
|
|
|
|
node* next;
|
|
|
|
|
|
|
|
node(const T& t, node* node): t(t), next(node)
|
|
|
|
{}
|
|
|
|
|
|
|
|
node(T&& t, node* node): t(std::move(t)), next(node)
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
node* head = nullptr;
|
|
|
|
public:
|
|
|
|
inline void push(const T& t)
|
|
|
|
{
|
|
|
|
head = new node(t, head);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void push(T&& t)
|
|
|
|
{
|
|
|
|
head = new node(std::move(t), head);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline T& top()
|
|
|
|
{
|
|
|
|
return head->t;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline const T& top() const
|
|
|
|
{
|
|
|
|
return head->t;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void pop()
|
|
|
|
{
|
|
|
|
auto* h = head;
|
|
|
|
head = head->next;
|
|
|
|
delete h;
|
|
|
|
}
|
|
|
|
|
|
|
|
~linked_stack()
|
|
|
|
{
|
|
|
|
auto* h = head;
|
|
|
|
while (h != nullptr)
|
|
|
|
{
|
|
|
|
auto* hc = h;
|
|
|
|
h = h->next;
|
|
|
|
delete hc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2022-12-26 00:31:00 -05:00
|
|
|
}
|
|
|
|
|
2023-01-05 12:34:14 -05:00
|
|
|
#endif //BLT_QUEUE_H
|