Index: doc/papers/OOPSLA17/evaluation/cpp-stack.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-stack.hpp	(revision 90152a4860529aff7214be01cd22abd37012cd19)
+++ doc/papers/OOPSLA17/evaluation/cpp-stack.hpp	(revision 90152a4860529aff7214be01cd22abd37012cd19)
@@ -0,0 +1,61 @@
+#pragma once
+#include <utility>
+
+template<typename T> class stack {
+	struct node {
+		T value;
+		node* next;
+
+		node( const T& v, node* n = nullptr ) : value(v), next(n) {}
+	};
+	node* head;
+
+	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;
+	}
+public:
+	void clear() {
+	    for ( node* next = head; next; ) {
+			node* crnt = next;
+			next = crnt->next;
+			delete crnt;
+		}
+		head = nullptr;
+	}
+
+	stack() : head(nullptr) {}
+	stack(const stack<T>& o) { copy(o); }
+	stack(stack<T>&& o) : head(o.head) { o.head = nullptr; }
+	~stack() { clear(); }
+
+	stack& operator= (const stack<T>& o) {
+		if ( this == &o ) return *this;
+		clear();
+		copy(o);
+		return *this;
+	}
+
+	stack& operator= (stack<T>&& o) {
+		if ( this == &o ) return *this;
+		head = o.head;
+		o.head = nullptr;
+		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 x = std::move(n->value);
+		delete n;
+		return x;
+	}
+};
