diff --git a/.idea/vcs.xml b/.idea/vcs.xml index f245aa7..9661ac7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,7 +1,6 @@ - \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 44205ec..ef0d355 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,5 @@ -cmake_minimum_required(VERSION 3.22) +cmake_minimum_required(VERSION 3.20) project(foreach C) set(CMAKE_C_STANDARD 99) - -include_directories(.) -add_executable(foreach test.c) +add_executable(foreach test.c foreach.h) diff --git a/foreach.h b/foreach.h index 0ce542c..785d3ee 100644 --- a/foreach.h +++ b/foreach.h @@ -1,11 +1,10 @@ #pragma once - -// Will determine the size of an array only if it is declared on the stack -// Need to dereference the item, as it is a pointer to the current element -#define foreach(type, item, array) \ - for (type* item = array; item < array + (sizeof(array) / sizeof(type)); item++) - -// Need to pass in the size of the array, since heap allocated arrays don't work with sizeof -// Need to dereference the item, as it is a pointer to the current element -#define foreach_p(type, item, array, size) \ +/* + * Need to pass in the size of the array, since pointer arrays don't know their size + * Can use sizeof(array) / sizeof(type) to get the size of the array if it is not a pointer + * Decays everything into pointers, as you cannot assign two different types in a for loop declaration + * For example, cannot do int* iter, int item = *iter, as they are different types + * You need to dereference the item, as it is a pointer to the current element + */ +#define foreach(type, item, array, size) \ for (type* item = array; item < array + size; item++) diff --git a/test.c b/test.c index 6b0c08c..d6e6e96 100644 --- a/test.c +++ b/test.c @@ -18,7 +18,7 @@ bool test_simpleArray() { int test[5]; int counter = 0; - foreach(int, item, arr) { + foreach(int, item, arr, sizeof(arr) / sizeof(int)) { test[counter] = *item; counter++; } @@ -33,7 +33,7 @@ bool test_simpleArray() { bool test_randomNumbers() { int arr1[10]; srand(0); - foreach(int, item, arr1) { + foreach(int, item, arr1, sizeof(arr1) / sizeof(int)) { *item = rand_range(0, 100); } int arr2[10]; @@ -48,13 +48,35 @@ bool test_randomNumbers() { } } +bool test_twoDimensionalArray() { + int arr2d[2][2] = { + {1, 2}, + {3, 4} + }; + int test[2][2]; + int counter1 = 0; + foreach(int*, arr, (int **) arr2d, 2) { + int counter2 = 0; + foreach(int, number, *arr, 2) { + test[counter1][counter2] = *number; + counter2++; + } + } + + if (memcmp(arr2d, test, sizeof(arr2d)) == 0) { + return true; + } else { + return false; + } +} + bool test_simpleString() { char *str = "Hello, World!"; // Plus one for the null terminator char test[strlen(str) + 1]; int counter = 0; - foreach_p(char, item, str, strlen(str) + 1) { + foreach(char, item, str, strlen(str) + 1) { test[counter] = *item; counter++; } @@ -71,7 +93,7 @@ bool test_simpleString() { bool test_randomNumbersAsPointers() { int arr1[10]; srand(0); - foreach_p(int, item, arr1, sizeof(arr1) / sizeof(int)) { + foreach(int, item, arr1, sizeof(arr1) / sizeof(int)) { *item = rand_range(0, 100); } int arr2[10]; @@ -90,7 +112,7 @@ bool test_randomNumbersAsPointers() { bool test_randomNumbersOnHeap() { int *arr1 = malloc(sizeof(int) * 10); srand(0); - foreach_p(int, item, arr1, 10) { + foreach(int, item, arr1, 10) { *item = rand_range(0, 100); } int *arr2 = malloc(sizeof(int) * 10); @@ -110,7 +132,7 @@ bool test_stringOnHeap() { strcpy(str, "Hello, World!"); char *test = malloc(sizeof(char) * 14); int counter = 0; - foreach_p(char, item, str, 14) { + foreach(char, item, str, 14) { test[counter] = *item; counter++; } @@ -122,36 +144,24 @@ bool test_stringOnHeap() { } int main() { - void* foreach_functions[] = { + void* functions[] = { test_simpleArray, test_randomNumbers, - }; - void* foreach_p_functions[] = { test_simpleString, test_randomNumbersAsPointers, test_randomNumbersOnHeap, - test_stringOnHeap + test_stringOnHeap, + test_twoDimensionalArray, }; - - printf("Foreach tests\n"); - for (int i = 0; i < sizeof(foreach_functions) / sizeof(void*); i++) { - bool result = ((bool (*)()) foreach_functions[i])(); + printf("foreach tests\n"); + for (int i = 0; i < sizeof(functions) / sizeof(void*); i++) { + bool result = ((bool (*)()) functions[i])(); if (result) { printf("Test %d passed\n", i); } else { printf("Test %d failed\n", i); } } - printf("Foreach_p tests\n"); - for (int i = 0; i < sizeof(foreach_p_functions) / sizeof(void*); i++) { - bool result = ((bool (*)()) foreach_p_functions[i])(); - if (result) { - printf("Test %d passed\n", i); - } else { - printf("Test %d failed\n", i); - } - } - return EXIT_SUCCESS; } #pragma clang diagnostic pop \ No newline at end of file