#ifndef EXT_SIMPLE_LIST_INCLUDED
#define EXT_SIMPLE_LIST_INCLUDED
namespace ext
{

template <class Ty>
class simple_list
{
	public:
		typedef Ty value_type;
		typedef Ty& reference;
		typedef const Ty& const_reference;
		typedef size_t size_type;
		
	private:
		struct node
		{
			node *next;
			value_type val;
		};
		
		node *m_head;
		node *m_last;
		size_type m_size;
	
	public:
		class const_iterator
		{
			protected:
				node *m_node;
			
			public:
				const_iterator() { }
				const_iterator(node *n) { m_node=n; }
				const_iterator& operator ++() { m_node=m_node->next; return *this; }
				const_iterator operator ++(int) { node *old=m_node; m_node=m_node->next; return const_iterator(old); }
				
				const_reference operator *() const { return m_node->val; }
				const_reference operator ->() const { return m_node->val; }
				
				bool operator ==(const_iterator& right) const { return m_node==right.m_node; }
				bool operator !=(const_iterator& right) const { return m_node!=right.m_node; }
		};
		
		class iterator : public const_iterator
		{
			public:
				iterator() { }
				iterator(node *n) : const_iterator(n) { }
				
				iterator& operator ++() { m_node=m_node->next; return *this; }
				iterator operator ++(int) { node *old=m_node; m_node=m_node->next; return iterator(old); }
				
				reference operator *() { return m_node->val; }
				reference operator ->() { return m_node->val; }
		};
		
	public:
		simple_list() { m_head=new node(); m_head->next=m_head; clear(); }
		simple_list(const simple_list& other)
		{
			m_head=new node(); m_head->next=m_head; clear();
			for(const_iterator &it=other.begin(); it!=other.end(); ++it){
				push_back(*it);
			}
		}
		
		~simple_list() { clear(); delete m_head; }
		
		void clear()
		{
			node *n, *old;
			for(old=0, n=m_head->next; n!=m_head; old=n, n=n->next){
				delete old;
			}
			delete old;
			
			m_head->next=m_head;
			m_last=m_head;
			m_size=0;
		}
		
		iterator begin() { return iterator(m_head->next); }
		iterator end() { return iterator(m_head); }
		
		const_iterator begin() const { return const_iterator(m_head->next); }
		const_iterator end() const { return const_iterator(m_head); }
		
		size_type size() const { return m_size; }
		
		iterator push_back(const_reference val)
		{
			node *n=new node();
			n->val=val;
			m_last->next=n;
			n->next=m_head;
			m_last=n;
			m_size++;
			return iterator(n);
		}
		
		reference front() { return *begin(); }
		reference back() { return m_last->val; }
		
		const_reference front() const { return *begin(); }
		const_reference back() const { return m_last->val; }
};

};

#endif // !defined(EXT_SIMPLE_LIST_INCLUDED)