Name: Anonymous 2010-05-01 17:42
subject.
#include <stdlib.h>
#include <stdarg.h>
typedef struct CContainer_VTable_s {
void *(*foldr)(void*, void*, void *(*)(void*, void*));
void *(*foldr1)(void*, void *(*)(void*, void*));
int (*count)(void*);
} CContainer_VTable;
typedef struct CContainer_s {
CContainer_VTable *vtable;
} CContainer;
#define DEFLL(t) \
struct LinkedList_s$##t { \
CContainer super; \
t value; \
struct LinkedList_s$##t *next; \
}; \
typedef struct LinkedList_s$##t LinkedList$##t; \
\
CContainer_VTable VTABLE_LinkedList$##t; \
\
int LinkedList$##t_count(void *p) \
{ \
LinkedList$##t *w = p; \
return w ? 1 + LinkedList$##t_count(w->next) : 0; \
} \
\
void *LinkedList$##t_foldr(void *p, void *z, void *(*f)(void*, void*)) \
{ \
LinkedList$##t *w = p; \
return w ? (*f)(&w->value, LinkedList$##t_foldr(w->next, z, f)) : z; \
} \
void *LinkedList$##t_foldr1(void *p, void *(*f)(void*, void*)) \
{ \
LinkedList$##t *w = p; \
return LinkedList$##t_foldr(w->next, &w->value, f); \
} \
\
LinkedList$##t *vnew_LinkedList$##t(int count, va_list args) \
{ \
LinkedList$##t *w = NULL; \
if (count) \
{ \
w = malloc(sizeof(LinkedList$##t)); \
w->super.vtable = &VTABLE_LinkedList$##t; \
w->value = va_arg(args, t); \
w->next = vnew_LinkedList$##t(count - 1, args); \
} \
return w; \
} \
LinkedList$##t *new_LinkedList$##t(int count, ...) \
{ \
va_list args; \
LinkedList$##t *w = NULL; \
va_start(args, count); \
w = vnew_LinkedList$##t(count, args); \
va_end(args); \
return w; \
} \
void delete_LinkedList$##t(LinkedList$##t *w) \
{ \
if (w) \
{ \
delete_LinkedList$##t(w->next); \
free(w); \
} \
}
#define INITLL(t) do { \
VTABLE_LinkedList$##t.foldr = &LinkedList$##t_foldr; \
VTABLE_LinkedList$##t.foldr1 = &LinkedList$##t_foldr1; \
VTABLE_LinkedList$##t.count = &LinkedList$##t_count; \
} while (0)
#define LL(t) LinkedList$##t
#define NEWLL(t) new_LinkedList$##t
#define DELETELL(t) delete_LinkedList$##t
DEFLL(int);
void *add(void *p, void *q)
{
int *a = p, *b = q, *r = malloc(sizeof(int));
*r = *a + *b;
return r;
}
int sum(int a, int b)
{
int *r;
LL(int) *l = NEWLL(int)(2, a, b);
r = l->super.vtable->foldr1(l, &add);
DELETELL(int)(l);
return *r;
}INITLL(int); somewhere before calling NEWLL(int)(...);. Implementing an add which doesn't leak memory is left as an exercise to the reader.