#pragma once
#include <utility>

template<typename T> struct stack {
	struct node {
		T value;
		node * next;
		node( const T & v, node * n = nullptr ) : value( v ), next( n ) {}
	};
	node * head;

	stack() : head( nullptr ) {}
	stack( const stack<T> & o ) { copy( o ); }

	void clear() {
		for ( node * next = head; next; ) {
			node * crnt = next;
			next = crnt->next;
			delete crnt;
		}
		head = nullptr;
	}

	void copy( const stack<T> & o ) {
		node ** crnt = &head;
		for ( node * next = o.head; next; next = next->next ) {
			*crnt = new node{ next->value }; /***/
			crnt = &(*crnt)->next;
		}
		*crnt = nullptr;
	}

	~stack() { clear(); }

	stack & operator= ( const stack<T> & o ) {
		if ( this == &o ) return *this;
		clear();
		copy( o );
		return *this;
	}

	bool empty() const { return head == nullptr; }

	void push( const T & value ) { head = new node{ value, head };  /***/ }

	T pop() {
		node * n = head;
		head = n->next;
		T v = std::move( n->value );
		delete n;
		return v;
	}
};
