/* Polymorphic lists in C */ #include #include #include typedef struct s_LHead { struct s_LHead * next; int type_tag; /* Not strictly necessary, but nice to have */ } LHead; #define NIL ((LHead *)0) /* Find the length of _any_ List */ /* Note this function is declared ahead of any particular list */ static int length(const LHead * list) { int count = 0; for(; list != NIL; list = list->next) count++; return count; } /* List of integers */ typedef struct s_LInt { LHead head; int datum; } LInt; #define LInt_type 1 /* List of numbers 0 .. n-1 */ /* Note that I went out of my way to avoid even implicit casts */ static LHead * iota(const int n) { register int i; register LInt * p = (LInt *)0; for(i=0; ihead).next = p == (LInt *)0 ? NIL : &(p->head); (p1->head).type_tag = LInt_type; p1->datum = i; p = p1; } return p == (LInt *)0 ? NIL : &(p->head); } /* List of strings */ typedef struct s_LStr { LHead head; const char * datum; } LStr; #define LStr_type 2 /* List of numbers 0 .. n-1 in their ASCII representation */ static LHead * iota_str(const int n) { register int i; register LStr * p = (LStr *)0; char buffer [40]; /* enough for MAXINT */ for(i=0; ihead).next = p == (LStr *)0 ? NIL : &(p->head); (p1->head).type_tag = LStr_type; snprintf(buffer,sizeof(buffer)-1, "%d",i); p1->datum = strdup(buffer); p = p1; } return p == (LStr *)0 ? NIL : &(p->head); } #define PR_TEST(X) printf("Length of " #X " is %d\n",length(X)) int main(void) { printf("Testing Polymorphic lists\n\n"); PR_TEST(NIL); PR_TEST(iota(5)); PR_TEST(iota_str(42)); return 0; }