diff --git a/include/mtl/queue.hpp b/include/mtl/queue.hpp new file mode 100644 index 0000000..6a3a187 --- /dev/null +++ b/include/mtl/queue.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include +#include + +#include + +namespace mtl { + +/** + * \brief Statically allocated queue + */ +template +class iqueue { +private: + T* m_buf; + size_t m_size; + const size_t m_capacity; + + size_t m_begin; + size_t m_end; + +public: + using value_type = T; + using size_type = size_t; + using reference = T&; + using const_reference = const T&; + + iqueue(T* buf, size_t capacity) noexcept : m_buf(buf), m_capacity(capacity), m_begin(0), m_end(0) {} + + reference front() noexcept { + return m_buf[m_begin]; + } + const_reference front() const noexcept { + return m_buf[m_begin]; + } + const_reference cfront() const noexcept { + return m_buf[m_begin]; + } + + reference back() noexcept { + return m_buf[m_end]; + } + const_reference back() const noexcept { + return m_buf[m_end]; + } + const_reference cback() const noexcept { + return m_buf[m_end]; + } + + bool empty() const noexcept { + return m_size == 0; + } + size_t size() const noexcept { + return m_size; + } + + void push(T value) { + if (m_size == m_capacity) { + throw mtl::length_error(); + } + + m_buf[m_end] = std::move(value); + + ++m_size; + + ++m_end; + m_end %= m_capacity; + } + void pop() noexcept { + if (m_size == 0) { + return; + } + + --m_size; + + ++m_begin; + m_begin %= m_capacity; + } +}; + +template +class queue : public iqueue { +private: + T m_buf[C]; + +public: + queue() noexcept : iqueue(m_buf, C) {} +}; + +} // namespace mtl +