#include <iostream>
using namespace std;

template <class x> class Node{
	//friend class List;//!!
public: //!!
	x data;
	Node<x> *next;
};

template <class x> class List{
private:
	Node<x> *cur;
	Node<x> *head;
	Node<x> *prev;
public:
	List();
	//~List();

	int		ListIsEmpty();
	int		ListIsFull();
	int		CurIsEmpty();
	void	ToFirst();
	int		AtFirst();
	int		AtEnd();
	void	Advance();
	void	InsertAfter(x e);
	void	Insert(x e);
	void	Delete();
	void	StoreInfo(x e);
	void	Error();

	x		RetrieveInfo();
	x		RetrieveNextInfo();
	Node<x>*	MakeNode(x e);
};

int main()
{
	List<int> l;
	l.Insert(2);
	l.Insert(4);
	l.Insert(6);
	l.Insert(8);
	int i;
	l.ToFirst();

	do
	{
		i = l.RetrieveInfo();
		cout << i;
		l.Advance();
	}while(!l.CurIsEmpty());

	return 0;
}


template <class x> List<x>::List(){
	cur = NULL;
	head = NULL;
	prev = NULL;
}

/*template <class x> List<x>::~List(){
	ToFirst();
	while(!ListIsEmpty()){
		Delete();
		Advance();
	}
}*/

template <class x> int List<x>::CurIsEmpty(){
	if (cur == NULL)
		return 1;
	else
		return 0;
}

template <class x> int List<x>::ListIsEmpty(){
	if (head == NULL)
		return 1;
	else
		return 0;
}

template <class x> int List<x>::ListIsFull(){
	return 0;
}

template <class x> void List<x>::ToFirst(){
	cur = head;
	prev = NULL;
}

template <class x> int List<x>::AtFirst(){
	return (cur == head ? 1 : 0);
}

template <class x> int List<x>::AtEnd(){
	if (ListIsEmpty())
		return 1;
	else if (CurIsEmpty())
		return 0;
	else if (cur->next == NULL)
		return 1;
	else
		return 0;
}

template <class x> void List<x>::Advance(){
	if (CurIsEmpty()){
		Error();
	}
	else{
		prev = cur;
		cur = cur->next;
	}
}

template <class x> void List<x>::InsertAfter(x e){
	Node<x> *p;
	p = MakeNode(e);
	if (ListIsEmpty()){
		head = p;
		cur = p;
		prev = NULL;
	}
	else if (CurIsEmpty()){
		Error();
	}
	else{
		p->next = cur->next;
		cur->next = p;
	}
}

template <class x> void List<x>::Insert(x e){
	Node<x> *p;
	p = MakeNode(e);
	if (ListIsEmpty()){
		head = p;
		cur = p;
		prev = NULL;
	}
	else if (AtFirst()){
		p->next = cur;
		head = p;
		cur = p;
	}
	else{
		p->next = cur;
		cur = p;
		prev->next = p;
	}
}

template <class x> void List<x>::Delete(){
	if (CurIsEmpty()){
		Error();
	}
	else if (AtFirst()){
		Node<x> *p;
		p = cur;
		cur = cur->next;
		head = cur;
		delete p;
	}
	else {
		Node<x> *p;
		p = cur;
		prev->next = cur->next;
		cur = cur->next;
		delete p;
	}
}

template <class x> void List<x>::StoreInfo(x e){
	if (CurIsEmpty()){
		Error();
	}
	else{
		cur->data = e;
	}
}

template <class x> x List<x>::RetrieveInfo(){
	if (CurIsEmpty()){
		Error();
		return -1;
	}
	else{
		return (cur->data);
	}
}

template <class x> x List<x>::RetrieveNextInfo(){
	if (ListIsEmpty() || CurIsEmpty() || AtEnd()){
		Error();
		return -1;
	}
	else{
		return (cur->next->data);
	}
}

template <class x> Node<x>* List<x>::MakeNode(x e){
	Node<x> *p;
	p = new Node<x>;
	p->data = e;
	p->next = NULL;
	return p;
}

template <class x> void List<x>::Error(){
	cout << "Error occured. no node exist!\n";
}