#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// single code implementation

struct list { void* value; struct list* next; };

// internal memory management requires helper functions

void list_insert( struct list** ls, void* x, void* (*copy)(void*) ) {
	struct list* node = malloc(sizeof(struct list));
	node->value = copy(x); node->next = *ls;
	*ls = node;
}

void* list_head( const struct list* ls ) { return ls->value; }

// helpers duplicated per type

void* int_copy(void* x) {
	int* n = malloc(sizeof(int));
	*n = *(int*)x;
	return n;
}

void* string_copy(void* x) { return strdup((const char*)x); }

int main() {
	struct list* il = NULL;
	int i = 42;
	list_insert( &il, &i, int_copy );
	printf("%d\n", *(int*)list_head(il));  // unsafe type cast
	
	struct list* sl = NULL;
	list_insert( &sl, "hello", string_copy );
	printf("%s\n", (char*)list_head(sl));
}