
#include <iostream>
using namespace std;

class list
{
	struct element {
		element* next;
		int value;

		element (int val) {
			value = val;
		}
	};

	element* head;

	void init() {
		head = nullptr;
	}

public:
	list() {
		init();
		cout << "constructed!" << endl;
	}

	list (const list& a) {
		init();
		element *i;
		for (i = a.head; i; i = i->next)
			push (i->value);
		cout << "Copy!!" << endl;


	}

	~list() {
		clear();
		cout << "destructed!" << endl;
	}

	void clear() {
		while (!empty()) pop();
	}

	void push (int 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.
	int 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;
	}
};

list create_list()
{
	list r;
	r.push (5);
	r.push (6);
	return r;
}

void print_out_list (list l)
{
	while (!l.empty()) {
		cout << l.front() << endl;
		l.pop();
	}
}

int main()
{
	list myList;
	myList.push (7);
	myList.push (3);
	myList.push (1);
	list secondList;
	secondList = create_list();
	print_out_list (secondList);
	print_out_list (myList);

	return 0;
}
