#import <ObjFW/ObjFW.h>
#include <gtk/gtk.h>

static void *copy(void *value)
{
	return [(id)value copy];
}

static void release(void *value)
{
	[(id)value release];
}

static uint32_t hash(void *value)
{
	return [(id)value hash];
}

static BOOL equal(void *value1, void *value2)
{
	return [(id)value1 isEqual: (id)value2];
}

static void *g_retain(void *value)
{
	return g_object_ref(value);
}

static void g_release(void *value)
{
	g_object_unref(value);
}

static void *default_retain(void *value)
{
	return value;
}

static uint32_t default_hash(void *value)
{
#define NUM (sizeof(void*)/sizeof(uint32_t))
	int i;
	uint32_t hash = 0;
	union {
		void *v;
		uint32_t i[NUM];
	} u = { value };

	for (i = 0; i < NUM; i++)
		hash ^= u.i[i];

	return hash;
#undef NUM
}

static BOOL default_equal(void *value1, void *value2)
{
	return (value1 == value2);
}


static void rowref_release(void *value)
{
	gtk_tree_row_reference_free(value);
}

of_map_table_functions_t keyFunctions = {
	.retain = copy,
	.release = release,
	.hash = hash,
	.equal = equal
};

of_map_table_functions_t gObjectFunctions = {
	.retain = g_retain,
	.release = g_release,
	.hash = default_hash,
	.equal = default_equal
};

of_map_table_functions_t rowRefFunctions = {
	.retain = default_retain,
	.release = rowref_release,
	.hash = default_hash,
	.equal = default_equal
};
