struct NestedLoopList {
int elem_size;
int length;
void* ptr;
int free_ptr; /* 0 = no, 1 = yes */
};
struct NestedLoopArrayArg {
int elem_size;
int length;
void* ptr;
};
struct NestedLoopFuncArg
void (*ptr)(struct NestedLoopList* list_ptr, void* pad);
void* pad;
};
struct NestedLoopArg {
int ptr_type; /* 0 = array, 1 = func */
union {
struct NestedLoopArrayArg array;
struct NestedLoopFuncArg func;
} ptr;
};
####
struct NestedLoopArg* args = (NestedLoopArg*)calloc(2, sizeof(NestedLoopArg));
args[0].ptr_type = 0; /* array */
args[0].ptr.array.elem_size = sizeof(int);
args[0].ptr.array.length = 5;
args[0].ptr.array.ptr = calloc(arg[0].array.length, arg[0].array.elem_size);
args[1].ptr_type = 1; /* func */
args[1].ptr.func.ptr = my_func;
struct MyFuncPad arg1_pad;
arg1_pad.count = 5;
args[1].ptr.func.pad = &arg1_pad;
NestedLoops(args);
... free memory allocated for args ...
##
##
struct NestedLoopList list;
if ((*arg_ptr).ptr_type == 0)
{
/* array */
struct NestedLoopArrayArg* array_ptr = (*arg_ptr).ptr;
list.elem_size = (*array_ptr).elem_size;
list.length = (*array_ptr).length;
list.ptr = (*array_ptr).ptr;
list.free_ptr = 0;
}
else
{
/* function */
struct NestedLoopFuncArg* func_ptr = (*arg_ptr).ptr;
(*(*func_ptr).ptr)(&list, (*func_ptr).pad);
}
##
##
struct MyFuncPad {
int count;
};
/* Creates a list of ints, numbered 1 to the int located at *pad. */
void my_func(struct NestedLoopList* list_ptr, void* pad) {
int count = (*(MyFuncPad*)pad).count;
int* array = (int*)calloc(count, sizeof(int));
int i;
for (i=0; i##
/* Convert the pointer to an int since ++ and other */
/* arithmentic operators are overloaded for pointers */
int p = (int)list.ptr;
for (i=0; i##
struct ElementType {
int size;
void (*handler )(void* ptr);
void (*destructor)(void* ptr);
};
struct Element {
struct ElementType* type_ptr
void* ptr;
};
struct NestedLoopList {
int length;
Element* ptr;
int free_ptr; /* 1 when ptr needs to be freed. */
int free_elems; /* 1 when each element of ptr[] needs to be freed and destroyed. */
};
struct NestedLoopArrayArg {
struct ElementType* type_ptr;
int length;
void* ptr;
};
struct NestedLoopMixedArg {
int length;
struct Element* ptr;
};
struct NestedLoopFuncArg {
void (*ptr)(struct NestedLoopList* list_ptr, void* pad);
void* pad;
};
struct NestedLoopArg {
int ptr_type; /* 0 = array, 1 = mixed array, 2 = func */
union {
struct NestedLoopArrayArg array;
struct NestedLoopMixedArg mixed;
struct NestedLoopFuncArg func;
} ptr;
};
##
##
struct NestedLoopArg* arg = (NestedLoopArg*)calloc(2, sizeof(NestedLoopArg));
args[0].ptr_type = 0; /* array */
args[0].ptr.array.type_ptr = &IntType;
args[0].ptr.array.length = 5;
args[0].ptr.array.ptr = calloc(arg[0].array.length, arg[0].array.elem_size);
args[1].ptr_type = 1; /* mixed array */
args[1].ptr.mixed.length = 4;
args[1].ptr.mixed.ptr = (Element*)calloc(arg[0].array.length, sizeof(struct Element));
{
... populate args[1].mixed.ptr[] ...
}
args[2].ptr_type = 2; /* func */
args[2].ptr.func.ptr = my_func;
struct MyFuncPad arg2_pad;
arg2_pad.count = 5;
args[2].ptr.func.pad = &arg2_pad;
NestedLoops(args);
... free memory allocated for args ...
##
##
struct NestedLoopList list;
switch ((*arg_ptr).ptr_type) {
case 0: /* array */
{
struct NestedLoopArrayArg* array_ptr = (*arg_ptr).ptr;
int length;
struct ElementType* type_ptr
int elem_size;
void* data_arr;
struct Element* elem_arr;
int src;
Element* dst;
int i;
length = (*array_ptr).length;
type_ptr = (*array_ptr).type_ptr;
elem_size = type_ptr.size;
data_arr = (*array_ptr).ptr;
elem_arr = (struct Element*)calloc(length, sizeof(struct Element));
/* Convert the pointer to an int since ++ and other */
/* arithmentic operators are overloaded for pointers */
src = (int)data_arr;
dst = elem_arr;
for (i=length; i--; ) {
(*dst).type_ptr = type_ptr;
(*dst).ptr = (void*)src;
src += elem_size;
dst++;
}
list.length = length;
list.ptr = elem_arr;
list.free_ptr = 1;
list.free_elems = 0;
break;
}
case 1: /* mixed array */
{
struct NestedLoopMixedArg* mixed_ptr = (*arg_ptr).ptr;
list.length = (*mixed_ptr).length
list.ptr = (*mixed_ptr).ptr;
list.free_ptr = 0;
list.free_elems = 0;
break;
}
case 2: /* func */
{
struct NestedLoopFuncArg* func = (*arg_ptr).ptr;
(*(*func_ptr).ptr)(&list, (*func_ptr).pad);
break;
}
}
##
##
struct MyFuncPad {
int count;
};
/* Creates a list of ints, numbered 1 to the int located at *pad. */
void my_func(struct NestedLoopList* list_ptr, void* pad) {
int count;
struct Element* elem_arr;
Element* dst;
int i;
count = (*(MyFuncPad*)pad).count;
elem_arr = (struct Element*)calloc(count, sizeof(struct Element));
dst = elem_arr;
for (i=0; i##
Element* elem_ptr = list.ptr;
for (i=0; i##
if (list.free_elems) {
int i;
Element* elem_ptr = list.ptr;
for (i=list.length; i--; ) {
(*(*(*elem_ptr).type_ptr).destructor)(elem_ptr.ptr);
free(elem_ptr.ptr);
elem_ptr++;
}
}
if (list.free_ptr) {
free(list.ptr);
}