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); }