Index: tests/zombies/wrapper/src/main.c
===================================================================
--- tests/zombies/wrapper/src/main.c	(revision 87b93323c11d412259391b6741a7bc4dcad8981e)
+++ tests/zombies/wrapper/src/main.c	(revision 87b93323c11d412259391b6741a7bc4dcad8981e)
@@ -0,0 +1,16 @@
+#include "pointer.h"
+
+wrapper_t make_copy(wrapper_t copy) {
+	return copy;
+}
+
+int main(int argc, char const *argv[]) {
+	wrapper_t p = wrap(6);
+	sout | nl | "test started";
+	wrapper_t p2 = p;
+	clear(&p);
+	p = p2;
+	wrapper_t p3 = make_copy(p2);
+	sout | nl | "test ended";
+	return 0;
+}
Index: tests/zombies/wrapper/src/pointer.h
===================================================================
--- tests/zombies/wrapper/src/pointer.h	(revision 87b93323c11d412259391b6741a7bc4dcad8981e)
+++ tests/zombies/wrapper/src/pointer.h	(revision 87b93323c11d412259391b6741a7bc4dcad8981e)
@@ -0,0 +1,122 @@
+#pragma once
+
+#include <fstream.hfa>
+#include <stddef.h>
+#include <stdlib.hfa>
+
+//==============================================================================
+// type safe malloc / free
+
+forall(otype T)
+T* new()
+{
+	T* p = malloc();
+	p{};
+	return p;
+}
+
+forall(otype T)
+void delete(T* p)
+{
+	^p{};
+	free(p);
+}
+
+//==============================================================================
+// ref counter content
+
+struct content_t
+{
+	int value;
+	size_t count;
+};
+
+void ?{}(content_t* this)
+{
+	sout | "Constructing content";
+	this->count = 0;
+}
+
+void ^?{}(content_t* this)
+{
+	sout | "Destroying content";
+}
+
+//==============================================================================
+// ref counter wrapper
+
+struct wrapper_t
+{
+	content_t* ptr;
+};
+
+void ?{}(wrapper_t* this)
+{
+	sout | "Constructing empty ref pointer" | nl;
+	this->ptr = NULL;
+}
+
+void ?{}(wrapper_t* this, wrapper_t rhs)
+{
+	sout | "Constructing ref pointer from copy";
+	this->ptr = rhs.ptr;
+	this->ptr->count++;
+	sout | "Reference is " | this->ptr->count | nl;
+}
+
+void ^?{}(wrapper_t* this)
+{
+	if(this->ptr)
+	{
+		sout | "Destroying ref pointer";
+		this->ptr->count--;
+		sout | "Reference is " | this->ptr->count | nl;
+		if(!this->ptr->count) delete(this->ptr);
+	}
+	else
+	{
+		sout | "Destroying empty ref pointer" | nl;
+	}
+}
+
+wrapper_t ?=?(wrapper_t* this, wrapper_t rhs)
+{
+	sout | "Setting ref pointer";
+	if(this->ptr)
+	{
+		this->ptr->count--;
+		sout | "Reference is " | this->ptr->count | nl;
+		if(!this->ptr->count) delete(this->ptr);
+	}
+	this->ptr = rhs.ptr;
+	this->ptr->count++;
+	sout | "Reference is " | this->ptr->count | nl;
+}
+
+void set(wrapper_t* this, content_t* c)
+{
+	this->ptr = c;
+	this->ptr->count++;
+	sout | "Setting ref pointer";
+	sout | "Reference is " | this->ptr->count | nl;
+}
+
+void clear(wrapper_t* this)
+{
+	sout | "Clearing ref pointer";
+	this->ptr->count--;
+	sout | "Reference is " | this->ptr->count | nl;
+	if(!this->ptr->count) delete(this->ptr);
+	this->ptr = NULL;
+}
+
+
+wrapper_t wrap(int val)
+{
+	wrapper_t w;
+	content_t* c = malloc();
+	c{};
+	c->value = val;
+	set(&w, c);
+	return w;
+}
