class List
{
private:
	class ListElement
	{
	public:		
		ListElement* next;
		int value;
	};

	ListElement* first;
	ListElement* last;
	int count;
public:
	List();
	~List();
		
	class Iterator
	{
	private:
		friend class List;
		ListElement* previousElement;
		ListElement* currentElement;

	public:
		Iterator(ListElement* previous, ListElement* current) { previousElement = previous, currentElement = current; }

		// inkrementacja iteratora (przejscie na nastepny element)
		Iterator& operator++(); // prefix
		Iterator operator++(int unused); // postfix

		// operator porownania
		bool operator== (const Iterator &iOther) { return currentElement == iOther.currentElement && previousElement == iOther.previousElement; }
		bool operator!= (const Iterator &iOther) { return currentElement != iOther.currentElement || previousElement != iOther.previousElement; }

		// iterator na nastepny element w liscie
		Iterator Next();

		// wyluskanie iteratora - zwrocenie wskaznika do ListElement::value
		int* operator*(void);
	};
	
	// iterator wskazujacy na pierwszy element w liscie
	Iterator Begin();

	// iterator oznaczajacy koniec listy ("element" PO OSTATNIM elemencie w liscie)
	Iterator End();

	// wstawienie nowego elementu do listy PRZED elementem na ktory wskazuje position
	// zwraca iterator na nowo dodany element zmienionej listy
	// uwaga: wywolanie Insert z position = End() ma dodac element na koniec listy
	Iterator Insert(Iterator position, int value);

	// usuniecie elementu wskazywanego przez position
	// zwraca iterator wskazujacy na element kolejny wzgledem position
	Iterator Remove(Iterator position);

	// zwraca wskaznik do wartosci elementu listy wskazywanego przez position
	int* ElementAt(Iterator position);

	// zwraca aktualna ilosc elementow w liscie
	int Count();
};
