#ifndef CircularDequeTemplate
#define CircularDequeTemplate
using namespace std;

template<class T> class CirDequeTemplate;
template<class T> std::ostream& operator<< (std::ostream& o, const CirDequeTemplate<T>& q);


template <class T>
class CirDequeTemplate {

private:
	T data[10];
	int front, rear;

public:
	CirDequeTemplate() { rear = front = 9; };
	void push_front(T);  // push an element to the front of the deque
	void push_back(T);   // push an element to the end of the deque
	T pop_front();       // pop an element from the front of the deque
	T pop_back();        // pop an element from the end of the deque
	friend ostream& operator<< <>(ostream&, const CirDequeTemplate&);
	// print the elements in queue from front to rear and separate each element by a space.
};
// you may write your code below this line

template<class T>
std::ostream &  operator<< (std::ostream &s, const CirDequeTemplate<T> &cird)
{
	for (int i = cird.front + 1; i <= cird.rear; i++)
	{
		if (i == cird.front + 1) printf("%d", cird.data[i]);
		else printf(" %d", cird.data[i]);
	}
	return s;
}
template<class T>
inline void CirDequeTemplate<T>::push_front(T a)
{
	if (rear - front == 9) { printf("queue is full\n"); return; }
	if (front == 0)
	{
		for (int i = rear; i >= 0; i--)data[i + 1] = data[i];
		front++;
		rear++;
	}
	data[front--] = a;
}
template<class T>
inline void CirDequeTemplate<T>::push_back(T a)
{
	if (rear - front == 9) { printf("queue is full\n"); return; }
	if (rear == 9)
	{
		for (int i = front; i <= 9; i++)data[i - 1] = data[i];
		rear--;
	}
	data[++rear] = a;
	front--;
}
template<class T>
inline T CirDequeTemplate<T>::pop_front()
{
	if (rear == front) { printf("queue is empty\n"); return 0; }
	front++;
	return data[front];//
}
template<class T>
inline T CirDequeTemplate<T>::pop_back()
{
	if (rear == front) { printf("queue is empty\n"); return 0; }
	rear--;
	return data[rear + 1];//+1

}
// you may write your code above this line
#endif