#include <stdlib>
#include "cfa-stack.h"

forall( otype T ) {
	struct node {
		T value;
		node(T) * next;
	};

	void ?{}( stack(T) & s, stack(T) t ) {		// copy
		node(T) ** cr = &s.head;
		for ( node(T) * nx = t.head; nx; nx = nx->next ) {
			*cr = alloc();
			((*cr)->value){ nx->value };
			cr = &(*cr)->next;
		}
		*cr = 0;
	}

	void clear( stack(T) & s ) with( s ) {
		for ( node(T) * nx = head; nx; ) {
			node(T) * cr = nx;
			nx = cr->next;
			^(*cr){};
			free( cr );
		}
		head = 0;
	}

	void ?{}( stack(T) & s ) { (s.head){ 0 }; }
	void ^?{}( stack(T) & s) { clear( s ); }

	stack(T) ?=?( stack(T) & s, stack(T) t ) {
		if ( s.head == t.head ) return s;
		clear( s );
		s{ t };
		return s;
	}

	_Bool empty( const stack(T) & s ) {
		return s.head == 0;
	}

	void push( stack(T) & s, T value ) with( s ) {
		node(T) * n = alloc();
		(*n){ value, head };
		head = n;
	}

	T pop( stack(T) & s ) with( s ) {
		node(T) * n = head;
		head = n->next;
		T v = n->value;
		^(*n){};
		free( n );
		return v;
	}
}
