/* -------------------- */ /* example3.c */ /* Example using function pointers. */ /* use Algorithm::Loops qw( NestedLoops ); my $depth = 3; my $max = 4; my $iter = NestedLoops( [ [ 0 .. $max ], ( sub { [$_+1..$max] } ) x ($depth-1), ] ); while (@list = $iter->()) { print(join(' ', @list), "\n"); } */ #include #include "nested_loops.h" struct RangePad { int min; int max; int* data; }; struct RangeIncPad { int max; int* data; }; void range_free(struct NestedLoop_List* list) { RangePad* pad; pad = (RangePad*)((*list).free_pad); free((*pad).data); (*pad).data = NULL; free((*list).ptr); (*list).ptr = NULL; } void range(struct NestedLoop_List* list, RangePad* pad) { int min; int max; int count; min = (*pad).min; max = (*pad).max; count = max - min + 1; if (count < 0) { count = 0; } free((*pad).data); (*pad).data = (int*)calloc(count, sizeof(int*)); { int* dst = (*pad).data; int i; for (i=min; i<=max; i++) { *(dst++) = i; } } (*list).length = count; (*list).free = &range_free; (*list).free_pad = pad; NestedLoops_to_ptr_array(&((*list).ptr), (*pad).data, count, sizeof(int)); } void range_inc_free(struct NestedLoop_List* list) { RangeIncPad* pad; pad = (RangeIncPad*)((*list).free_pad); free((*pad).data); (*pad).data = NULL; free((*list).ptr); (*list).ptr = NULL; } void range_inc(struct NestedLoop_List* list, RangeIncPad* pad) { int min; int max; int count; min = (*list).ptr[(*list).length - 2] + 1; max = (*pad).max; count = max - min + 1; if (count < 0) { count = 0; } { int* dst = (*pad).data; int i; for (i=min; i<=max; i++) { *(dst++) = i; } } free((*pad).data); (*pad).data = (int*)calloc(count, sizeof(int*)); (*list).length = count; (*list).free = &range_inc_free; (*list).free_pad = pad; NestedLoops_to_ptr_array(&((*list).ptr), (*pad).data, count, sizeof(int)); } void main() { /* This could be built dynamically. */ /* The args must remain accessible until done. */ /* NL's caller (i.e. us) handles cleanup of args. */ struct NestedLoop_Arg args[3]; struct RangePad pad0; struct RangeIncPad pad[2]; pad0.min = 1; pad0.max = 4; pad0.data = NULL; args[0].ptr_type = NestedLoop_PT_FUNC; args[0].ptr.func.ptr = ⦥ args[0].ptr.func.pad = &(pad[0]); pad[1-1].max = 4; pad[1-1].data = NULL; args[1].ptr_type = NestedLoop_PT_FUNC; args[1].ptr.func.ptr = &range_inc; args[1].ptr.func.pad = &(pad[1-1]); pad[2-1].max = 4; pad[2-1].data = NULL; args[2].ptr_type = NestedLoop_PT_FUNC; args[2].ptr.func.ptr = &range_inc; args[2].ptr.func.pad = &(pad[2-1]); { struct NestedLoop_Iter iter; NestedLoops_get_iter(&iter, sizeof(args)/sizeof(args[0]), args); while (NestedLoops_fetch(&iter)) { int i; /* Skip results without an element from each loop. */ if (iter.list.length != iter.num_loops) { continue; } for (i=0; i