#pragma once #include template class Queue { T* data; size_t capacity; size_t count; size_t head; //where to get size_t tail; //last added element; void resize(size_t newCapacity); void copyFrom(const Queue& other); void free(); public: Queue(); Queue(const Queue& other); Queue& operator=(const Queue& other); void enqueue(const T& obj); T dequeue(); size_t getCount(); size_t isEmpty(); ~Queue(); }; template Queue::Queue() { capacity = 4; data = new T[capacity]; count = 0; head = tail = 0; } template void Queue::enqueue(const T& obj) { if (count == capacity) resize(capacity * 2); if (count != 0) tail++; tail %= capacity; //so we don't get an out of range exception data[tail] = obj; count++; } template T Queue::dequeue() { if (count == 0) throw std::exception("The collection is empty!"); T toReturn = data[head]; (++head) %= capacity; count--; return toReturn; } template size_t Queue::getCount() { return count; } template size_t Queue::isEmpty() { return getCount() == 0; } template void Queue::resize(size_t newCapacity) { T* newData = new T[newCapacity]; for (int i = 0, ind = head; i < count; i++, (++ind) %= capacity) newData[i] = data[ind]; delete[] data; capacity = newCapacity; data = newData; head = 0; tail = count - 1; } template void Queue::copyFrom(const Queue& other) { data = new T[other.capacity]; for (int i = 0; i < other.capacity; i++) data[i] = other.data[i]; head = other.head; tail = other.tail; count = other.count; capacity = other.capacity; } template void Queue::free() { delete[] data; } template Queue::Queue(const Queue& other) { copyFrom(other); } template Queue& Queue::operator=(const Queue& other) { if (this != &other) { free(); copyFrom(other); } return *this; } template Queue::~Queue() { free(); }