//! \addtogroup Containers
//! \{
//! \~\file piqueue.h
//! \brief
//! \~english Declares \a PIQueue
//! \~russian Объявление \a PIQueue
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//! \~\}
/*
    PIP - Platform Independent Primitives
    Queue container
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PIQUEUE_H
#define PIQUEUE_H

#include "pideque.h"
#include "pivector.h"

//! \addtogroup Containers
//! \{
//! \class PIQueue
//! \~\brief
//! \~english Queue container built on top of \a PIDeque.
//! \~russian Контейнер очереди, построенный поверх \a PIDeque.
//! \~\}
//! \details
//! \~english Stores elements in FIFO order and adds \a enqueue() and \a dequeue() to \a PIDeque.
//! \~russian Хранит элементы в порядке FIFO и добавляет к \a PIDeque функции \a enqueue() и \a dequeue().
//! \~\sa \a PIDeque
template<typename T>
class PIQueue: public PIDeque<T> {
public:
	//! \~english Constructs an empty queue.
	//! \~russian Создает пустую очередь.
	PIQueue() {}

	//! \~english Enqueues `v`.
	//! \~russian Добавляет `v` в очередь.
	PIDeque<T> & enqueue(const T & v) {
		PIDeque<T>::push_front(v);
		return *this;
	}

	//! \~english Moves `v` into the queue.
	//! \~russian Перемещает `v` в очередь.
	PIDeque<T> & enqueue(T && v) {
		PIDeque<T>::push_front(std::move(v));
		return *this;
	}

	//! \~english Dequeues and returns the head element.
	//! \~russian Извлекает и возвращает головной элемент очереди.
	//! \~\details
	//! \note
	//! \~english This function assumes that the queue is not empty.
	//! Otherwise behavior is undefined.
	//! \~russian Эта функция предполагает, что очередь не пуста.
	//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
	T dequeue() { return PIDeque<T>::take_back(); }

	//! \~english Returns the head element.
	//! \~russian Возвращает головной элемент очереди.
	//! \~\details
	//! \note
	//! \~english Returns a reference to the head element.
	//! This function assumes that the queue is not empty.
	//! Otherwise behavior is undefined.
	//! \~russian Возвращает ссылку на головной элемент очереди.
	//! Эта функция предполагает, что очередь не пуста.
	//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
	T & head() { return PIDeque<T>::back(); }
	const T & head() const { return PIDeque<T>::back(); }

	//! \~english Returns the tail element.
	//! \~russian Возвращает хвостовой элемент очереди.
	//! \~\details
	//! \~english Returns a reference to the tail element.
	//! This function assumes that the queue is not empty.
	//! Otherwise behavior is undefined.
	//! \~russian Возвращает ссылку на хвостовой элемент очереди.
	//! Эта функция предполагает, что очередь не пуста.
	//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
	T & tail() { return PIDeque<T>::front(); }
	const T & tail() const { return PIDeque<T>::front(); }

	//! \~english Returns queue contents as \a PIVector.
	//! \~russian Возвращает содержимое очереди в виде \a PIVector.
	PIVector<T> toVector() const { return PIVector<T>(PIDeque<T>::data(), PIDeque<T>::size()); }

	//! \~english Returns queue contents as \a PIDeque.
	//! \~russian Возвращает содержимое очереди в виде \a PIDeque.
	PIDeque<T> toDeque() const { return PIDeque<T>(*this); }
};

#endif // PIQUEUE_H
