
#include <iostream>;
using namespace std;


template <typename T> class list
{
	struct list_elem {
		T value;
		list_elem* next;
	};

	list_elem* head;

public:
	list() {
		//cout << "list()" << endl;
		init();
	}

	~list() {
		//cout << "~list()" << endl;
		clear();
	}

	list (const list& x) {
		//cout << "copy" << endl;
		init();
		*this = x;
	}

	list& operator= (const list& a) {
		//cout << "op=" << endl;
		clear();
		for (list_elem* i = a.head ; i; i = i->next) {
			push (i->value);
		}

		//reverse the list
		list_elem*n = nullptr;
		while (head) {
			list_elem*tmp = head->next;
			head->next = n;
			n = head;
			head = tmp;
		}

		head = n;

		return *this;
	}

	void push (const T& value) {
		list_elem *elem = new list_elem();
		elem->value = value;
		elem->next = head;
		head = elem;
	}
	void pop() {
		list_elem * next = head->next;
		delete head;
		head = next;
	}

	void clear() {
		while (!empty())
			pop();
	}

	bool empty() const {
		return !head;
	}

	T& front() const {
		return head->value;
	}

private:
	void init() {
		head = nullptr;
	}
};

template <typename T> list<T> demo_list()
{
	list<T> r;
	r.push (5);
	r.push (1);
	r.push (4);
	return r;
}

template <typename T> void print_list (list<T> l)
{
	while (!l.empty()) {
		cout << l.front() << endl;
		l.pop();
	}
}

template<typename T> ostream& operator<< (ostream& out, list<T> l)
{
	out << "( ";
	while (!l.empty()) {
		out << l.front() << ' ';
		l.pop();
	}
	out << ")";
	return out;
}
int main()
{
	//list<float> l;
	//l = demo_list<float>();
	//
	//list<float> l2;
	//l2 = l;

	list<list<int>> l;

	list<int> xx (demo_list<int>());

	l.push (xx);
	l.push (xx);
	l.push (xx);
	l.push (xx);

	l.front().front() += 5;

	//print_list(l);
	cout << l << endl;
	return 0;
}

