#include "cpp-vstack.hpp"
#include <utility>

stack::node::node( const object& v, node* n ) : value( v.new_copy() ), next( n ) {}

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

stack::stack() : head(nullptr) {}
stack::stack(const stack& o) { copy(o); }
stack::stack(stack&& o) : head(o.head) { o.head = nullptr; }
stack::~stack() { clear(); }

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

stack& stack::operator= (stack&& o) {
	if ( this == &o ) return *this;
	head = o.head;
	o.head = nullptr;
	return *this;
}

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


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

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

ptr<object> stack::pop() {
	node* n = head;
	head = n->next;
	ptr<object> x = std::move(n->value);
	delete n;
	return x;
}
