diff --git a/lib_queue/CMakeLists.txt b/lib_queue/CMakeLists.txt new file mode 100644 index 00000000..d918c89d --- /dev/null +++ b/lib_queue/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Queue) diff --git a/lib_queue/queue.cpp b/lib_queue/queue.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_queue/queue.h b/lib_queue/queue.h new file mode 100644 index 00000000..0cc4fbd3 --- /dev/null +++ b/lib_queue/queue.h @@ -0,0 +1,160 @@ +template +class Queue { + T* _data; + int _head; + int _count; + int _capacity; + +public: + + Queue(int capacity = 15); + Queue(const Queue& other); + ~Queue(); + + Queue& operator=(const Queue& other); + Queue& operator=(Queue&& other) noexcept; + void enqueue(const T& value); + T dequeue(); + T& front(); + const T& front() const; + T& back(); + const T& back() const; + bool empty() const; + bool full() const; + int size() const; + int capacity() const; + void clear(); + int tail() const; + +}; + +template +Queue::Queue(int capacity) : _data(new T[capacity]), _head(0), _count(0), _capacity(capacity){} + +template +Queue::Queue(const Queue& other) : _data(new T[other._capacity]), _head(other._head), _count(other._count), _capacity(other._capacity) { + for (int i = 0; i < _count; i++) { + _data[(i + _head) % _capacity] = other._data[(i + other._head) % other._capacity]; + } +} + +template +Queue::~Queue() { + delete[] _data; +} + +template +Queue& Queue::operator=(const Queue& other) { + if (this != &other) { + delete[] _data; + _capacity = other._capacity; + _head = other._head; + _count = other._count; + _data = new T[_capacity]; + + for (int i = 0; i < _count; i++) { + _data[(i + _head) % _capacity] = other._data[(i + other._head) % other._capacity]; + } + } + return *this; +} + +template +Queue& Queue::operator=(Queue&& other) noexcept { + if (this != &other) { + delete[] _data; + _data = other._data; + _head = other._head; + _count = other._count; + _capacity = other._capacity; + + other._data = nullptr; + other._head = 0; + other._count = 0; + other._capacity = 0; + } + return *this; +} + +template +void Queue::enqueue(const T& value) { + if (full()) { + resize(_capacity * 2); + } + _data[tail()] = value; + _count++; +} + +template +T Queue::dequeue() { + if (empty()) { + throw std::runtime_error("Queue is empty"); + } + T value = std::move(_data[_head]); + _head = (_head + 1) % _capacity; + _count--; + return value; +} + +template +T& Queue::front() { + if (empty()) { + throw std::runtime_error("Queue is empty"); + } + return _data[_head]; +} + +template +const T& Queue::front() const { + if (empty()) { + throw std::runtime_error("Queue is empty"); + } + return _data[_head]; +} + +template +T& Queue::back() { + if (empty()) { + throw std::runtime_error("Queue is empty"); + } + return _data[tail() - 1]; +} + +template +const T& Queue::back() const { + if (empty()) { + throw std::runtime_error("Queue is empty"); + } + return _data[tail() - 1]; +} + +template +bool Queue::empty() const { + return _count == 0; +} + +template +bool Queue::full() const { + return _count == _capacity; +} + +template +int Queue::size() const { + return _count; +} + +template +int Queue::capacity() const { + return _capacity; +} + +template +void Queue::clear() { + _head = 0; + _count = 0; +} + +template +int Queue::tail() const { + return (_head + _count) % _capacity; +}