Loop over multiple arrays simultaneously/C-Elaboration
<lang c>#include <stdio.h>
typedef struct closure {
void (*f)( void *elem, void *data); void *data;
} *Closure;
typedef struct listSpec{
void (*print)(const void *); void *ary; int count; size_t elem_size;
} *ListSpec;
- define LIST_SPEC( pf,typ,aa) {pf, aa, (sizeof(aa)/sizeof(typ)), sizeof(typ) }
/* calls closure's function f for each element in list */
void DoForEach( Closure c, ListSpec aspec )
{
int i; void *val_ptr; for (i=0, val_ptr=aspec->ary; i< aspec->count; i++) { (*c->f)(val_ptr, c->data); val_ptr = ((char *)val_ptr) + aspec->elem_size; }
}
/* Used to find the minimum array length of list of lists */ void FindMin( ListSpec *paspec, int *minCount ) {
ListSpec aspec = *paspec; if (*minCount>aspec->count) *minCount = aspec->count;
}
/* prints an element of a list using the list's print function */ void PrintElement( ListSpec *paspec, int *indx ) {
ListSpec aspec = *paspec; (*aspec->print)( ((char*)aspec->ary) + (*indx)*aspec->elem_size);
}
/* Loop Over multiple lists (a list of lists)*/
void LoopMultiple( ListSpec arrays)
{
int indx; int minCount = 100000; struct closure c1 = { &FindMin, &minCount }; struct closure xclsr = { &PrintElement, &indx }; DoForEach( &c1, arrays); printf("min count = %d\n", minCount);
for (indx=0; indx<minCount; indx++) { DoForEach(&xclsr, arrays ); printf("\n"); }
}
/* Defining our Lists */
void PrintInt(const int *ival) { printf("%3d,", *ival); } int ary1[] = { 6,5,4,9,8,7 }; struct listSpec lspec1 = LIST_SPEC( &PrintInt, int, ary1 );
void PrintShort(const short *ival) { printf("%3d,", *ival); } short ary2[] = { 3, 66, 20, 15, 7, 22, 10 }; struct listSpec lspec2 = LIST_SPEC( &PrintShort , short, ary2 );
void PrintStrg(const char *const *strg ) { printf(" %s", *strg); } const char *ary3[] = {"Hello", "all", "you","good", "folks","out", "there" }; struct listSpec lspec3 = LIST_SPEC( &PrintStrg , const char *, ary3 );
void PrintLstSpec(const ListSpec *ls) { printf("not-implemented"); } ListSpec listList[] = { &lspec1, &lspec2, &lspec3 }; struct listSpec llSpec = LIST_SPEC(&PrintLstSpec, ListSpec, listList);
int main(int argc, char *argv[]) {
LoopMultiple( &llSpec); return 0;
}</lang>