/* loops through 2D array in order of 3x3 submaps */ void UArray2_map_3x3_box(UArray2_T uarray2, void apply(int col, int row, UArray2_T a, void *elem, void *cl), void *cl) { int c, r; assert(uarray2); assert(apply); for (r = 0; r < UArray2_height(uarray2); r++) { for (c = 0; c < 3; c++) { apply(c, r, uarray2, UArray2_at(uarray2, c, r), cl); } } for (r = 0; r < UArray2_height(uarray2); r++) { for (c = 3; c < 6; c++) { apply(c, r, uarray2, UArray2_at(uarray2, c, r), cl); } } for (r = 0; r < UArray2_height(uarray2); r++) { for (c = 6; c < 9; c++) { apply(c, r, uarray2, UArray2_at(uarray2, c, r), cl); } } }
int main(int argc, char *argv[]) { (void)argc; (void)argv; UArray2_T test_array; bool OK = true; test_array = UArray2_new(DIM1, DIM2, ELEMENT_SIZE); //These functions check that the dimension has been set correctly OK &= (UArray2_width(test_array) == DIM1); OK &= (UArray2_height(test_array) == DIM2); OK &= (UArray2_size(test_array) == ELEMENT_SIZE); /* Note: we are only setting a value on the corner of the array */ *((number *)UArray2_at(test_array, DIM1-1, DIM2-1)) = MARKER; printf("Trying column major\n"); UArray2_map_col_major(test_array, check_and_print, &OK); printf("Trying row major\n"); UArray2_map_row_major(test_array, check_and_print, &OK); printf(" width = %d\n", UArray2_width(test_array)); printf("height %d\n", UArray2_height(test_array)); UArray2_free(&test_array); printf("The array is %sOK!\n", (OK ? "" : "NOT ")); }
/*-----------------------------------------------------------------------------* | UArray2_at | Purpose: finds the element stored at the specified matrix location of | the given UArray2 | Arguments: a pointer to a 2D array, the matrix location to be accessed | as a pair of ints | Returns: a pointer to the element at the given matrix location | Fail cases: | - the pointer to the 2D array is null | - the matrix location lies outside of the bounds of the 2D array *-----------------------------------------------------------------------------*/ void *UArray2_at(UArray2_T uarray2, int i, int j) { assert(uarray2 != NULL); assert((i >= 0 && i < UArray2_width(uarray2)) && (j >= 0 && j < UArray2_height(uarray2))); int index = get_index(i, j, UArray2_height(uarray2)); return UArray_at(uarray2->uarray, index); }
/*-----------------------------------------------------------------------------* | UArray2_map_col_major | Purpose: maps the given function onto every element of the given | UArray2 in col major order | Arguments: a pointer to the 2D array, a pointer to a void apply | function, the closure as a void * | Returns: - | Fail cases: | - the pointer to the 2D array is null | - the pointer to the apply function is null *-----------------------------------------------------------------------------*/ void UArray2_map_col_major(UArray2_T uarray2, void apply(int i, int j, UArray2_T uarray2, void *value, void *cl), void *cl) { assert(uarray2 != NULL); assert(apply != NULL); int index; int i; int j; for (index = 0; index < UArray_length(uarray2->uarray); index ++) { i = get_i(index, UArray2_height(uarray2)); j = get_j(index, UArray2_height(uarray2)); apply(i, j, uarray2, UArray2_at(uarray2, i, j), cl); }; }
/*-----------------------------------------------------------------------------* | UArray2_map_row_major | Purpose: maps the given function onto every element of the given | UArray2 in row major order | Arguments: a pointer to the 2D array, a pointer to a void apply | function, the closure as a void * | Returns: - | Fail cases: | - the pointer to the 2D array is null | - the pointer to the apply function is null *-----------------------------------------------------------------------------*/ void UArray2_map_row_major(UArray2_T uarray2, void apply(int i, int j, UArray2_T uarray2, void *value, void *cl), void *cl) { assert(uarray2 != NULL); assert(apply != NULL); int i; int j; for (j = 0; j < UArray2_height(uarray2); j++) { for (i = 0; i < UArray2_width(uarray2); i++) { apply(i, j, uarray2, UArray2_at(uarray2, i, j), cl); }; }; }
void UArray2b_free(T *array2b) { assert(array2b && *array2b); T a2b = *array2b; int bwidth = UArray2_width(a2b->blocks); int bheight = UArray2_height(a2b->blocks); for (int i=0; i<bwidth; i++) { for (int j=0; j<bheight; j++) { UArray_free(UArray2_at(a2b->blocks,i,j)); } } UArray2_free(&(a2b->blocks)); free(*array2b); *array2b = NULL; }
void UArray2b_map(T array2b, void apply(), void* cl) { assert(array2b); int blocksize = array2b->blocksize; int max = blocksize * blocksize; int bheight = UArray2_height(array2b->blocks); int bwidth = UArray2_width(array2b->blocks); for(int blockj = 0; blockj < bheight; blockj++) { for(int blocki = 0; blocki < bwidth; blocki++) { UArray_T *temp = UArray2_at(array2b->blocks, blocki, blockj); for(int n = 0; n < max; n++) { /* n == blocksize * (i % blocksize) + (j % blocksize) n / blocksize == i % blocksize n % blocksize == j % blocksize */ int i = blocki*blocksize + n%blocksize; int j = blockj*blocksize + n/blocksize; if(i < array2b->width && j < array2b->height) apply(i, j, array2b, UArray_at(*temp, n), cl); } } } }