
#include <iostream>
using namespace std;

template<typename T>
class list
{
	struct element {
		element* next;
		T value;

		element(T val) {
			value = val;
		}
	};

	element* head;

	void init() {
		head = nullptr;
	}

public:
	list() {
		init();
	}

	list(const list& a) {
		init();
		element *i;
		for (i = a.head; i; i = i->next)
			push(i->value);
	}

	~list() {
		clear();
	}

	void clear() {
		while (!empty()) pop();
	}

	void push(const T& val) {
		element *newEl = new element(val);
		newEl->next = head;
		head = newEl;
	}

	bool empty() const {
		return !head;
	}

	// don't use this on empty list
	//there will be UB.
	T& front() const {
		return head->value;
	}

	void pop() {
		element *p = head->next;
		delete head;
		head = p;
	}

	list& operator= (const list& a) {
		clear();

		element *i;
		for (i = a.head; i; i = i->next)
			push(i->value);
		return *this;
	}
};

template <typename T>
list<T> create_list()
{
	list<T> r;
	r.push(5);
	r.push(6);
	return r;
}

template <typename T>
void print_out_list(list<T> l)
{
	while (!l.empty()) {
		cout << l.front() << endl;
		l.pop();
	}
}

template <typename T>
ostream& operator<<(ostream& o, list<T> l) {
	o << '(';
	while (!l.empty()) {
		o << l.front() << ' ';
		l.pop();
	}
	o << ')';
	return o;
}


int main()
{
	list<float> myList;
	myList.push(7);
	myList.push(3);
	myList.push(1);
	list<list<float>> ll;
	ll.push(myList);
	ll.push(myList);
	ll.push(myList);

	cout << ll << endl;

	return 0;
}
