#pragma once template class Deque { // class iterator; private: int _head, _tail; T _data[Size]; public: Deque() { clear(); }; size_t free(); const size_t size() const; const size_t max_size() const; T & front(); const T & front() const; T & back(); const T & back() const; void push_front(const T &); void push_back(const T &); T pop_front(); T pop_back(); T& operator[](size_t); const T& operator[](size_t) const; T& at(size_t); const T& at(size_t) const; void clear(); // iterator begin(); // iterator end(); void erase(size_t); void erase(size_t, size_t); bool empty() const { return size() == 0; } bool full() const { return (size() == Size); } }; template size_t Deque::free() { return Size - size(); } template const size_t Deque::size() const { if (_tail < 0) return 0; // empty else if (_head > _tail) return _head - _tail; else return Size - _tail + _head; } template const size_t Deque::max_size() const { return Size; } template T & Deque::front() { return _data[_tail]; } template const T & Deque::front() const { return _data[_tail]; } template T & Deque::back() { int idx = _head - 1; if (idx < 0) idx = Size - 1; return _data[idx]; } template const T & Deque::back() const { int idx = _head - 1; if (idx < 0) idx = Size - 1; return _data[idx]; } template void Deque::push_front(const T &value) { //if container is full, do nothing. if (free()){ if (--_tail < 0) _tail = Size - 1; _data[_tail] = value; } } template void Deque::push_back(const T &value) { //if container is full, do nothing. if (free()){ _data[_head] = value; if (empty()) _tail = _head; if (++_head >= Size) _head %= Size; } } template T Deque::pop_front() { if (empty()) // if empty, do nothing. return T(); auto item = front(); if (++_tail >= Size) _tail %= Size; if (_tail == _head) clear(); return item; } template T Deque::pop_back() { if (empty()) // if empty, do nothing. return T(); auto item = front(); if (--_head < 0) _head = Size - 1; if (_head == _tail) //now buffer is empty clear(); return item; } template void Deque::erase(size_t position) { if (position >= size()) // out-of-range! return; // do nothing. for (size_t i = position; i < size() - 1; i++){ at(i) = at(i + 1); } pop_back(); } template void Deque::erase(size_t first, size_t last) { if (first > last // invalid arguments || first >= size()) // out-of-range return; //do nothing. size_t tgt = first; for (size_t i = last + 1; i < size(); i++){ at(tgt++) = at(i); } for (size_t i = first; i <= last; i++){ pop_back(); } } template T& Deque::operator[](size_t index) { auto i = _tail + index; if (i >= Size) i %= Size; return _data[i]; } template const T& Deque::operator[](size_t index) const { auto i = _tail + index; if (i >= Size) i %= Size; return _data[i]; } template T& Deque::at(size_t index) { auto i = _tail + index; if (i >= Size) i %= Size; return _data[i]; } template const T& Deque::at(size_t index) const { auto i = _tail + index; if (i >= Size) i %= Size; return _data[i]; } template void Deque::clear() { _tail = -1; _head = 0; }