#ifndef __LIST_H__
#define __LIST_H__

#include <stdint.h>

#define Null	0L

template <typename T>
class list
{
	public:

		list() : head( Null ), tail ( Null ) {}

		template<int N>
		list( T (&arr) [N]) : head( Null ), tail ( Null )
		{
			for( int i(0); i != N; ++i)
				push_back(arr[i]);
		}

		bool empty() const { return ( !head || !tail ); }
		operator bool() const { return !empty(); }
		void push_back(T);
		void push_front(T);
		T pop_back();
		T pop_front();

		~list();

	private:
	    struct node
	    {
	        T		data;
	        node* 	prev;
	        node* 	next;
	        node(T t, node* p, node* n) : data(t), prev(p), next(n) {}
	    };
	    node* head;
	    node* tail;
};

template <typename T>
list<T>::~list()
{
	while(head) {
		node* temp(head);
		head=head->next;
		delete temp;
	}
}

template <typename T>
void list<T>::push_back(T data)
{
    tail = new node(data, tail, Null);
    if( tail->prev )
        tail->prev->next = tail;

    if( empty() )
        head = tail;
}

template <typename T>
void list<T>::push_front(T data)
{
    head = new node(data, Null, head);
    if( head->next )
        head->next->prev = head;

    if( empty() )
        tail = head;
}

template<typename T>
T list<T>::pop_back()
{
//   if( empty() )
//       throw("list : list empty");
    node* temp(tail);
    T data( tail->data );
    tail = tail->prev ;

    if( tail )
        tail->next = Null;
    else
        head = Null ;

    delete temp;
    return data;
}

template<typename T>
T list<T>::pop_front()
{
//    if( empty() )
 //       throw("list : list empty");
    node* temp(head);
    T data( head->data );
    head = head->next ;

    if( head )
        head->prev = Null;
    else
        tail = Null;

    delete temp;
    return data;
}

#endif // __LIST_H__
