Change macro

This commit is contained in:
Isaac Shoebottom 2023-11-17 14:14:55 -04:00
parent 27b42b6ed1
commit 4d8bdf6f1e
4 changed files with 44 additions and 38 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
</component> </component>
</project> </project>

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.20)
project(foreach C) project(foreach C)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
add_executable(foreach test.c foreach.h)
include_directories(.)
add_executable(foreach test.c)

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
/*
// Will determine the size of an array only if it is declared on the stack * Need to pass in the size of the array, since pointer arrays don't know their size
// Need to dereference the item, as it is a pointer to the current element * Can use sizeof(array) / sizeof(type) to get the size of the array if it is not a pointer
#define foreach(type, item, array) \ * Decays everything into pointers, as you cannot assign two different types in a for loop declaration
for (type* item = array; item < array + (sizeof(array) / sizeof(type)); item++) * 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
// 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(type, item, array, size) \
#define foreach_p(type, item, array, size) \
for (type* item = array; item < array + size; item++) for (type* item = array; item < array + size; item++)

58
test.c
View File

@ -18,7 +18,7 @@ bool test_simpleArray() {
int test[5]; int test[5];
int counter = 0; int counter = 0;
foreach(int, item, arr) { foreach(int, item, arr, sizeof(arr) / sizeof(int)) {
test[counter] = *item; test[counter] = *item;
counter++; counter++;
} }
@ -33,7 +33,7 @@ bool test_simpleArray() {
bool test_randomNumbers() { bool test_randomNumbers() {
int arr1[10]; int arr1[10];
srand(0); srand(0);
foreach(int, item, arr1) { foreach(int, item, arr1, sizeof(arr1) / sizeof(int)) {
*item = rand_range(0, 100); *item = rand_range(0, 100);
} }
int arr2[10]; 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() { bool test_simpleString() {
char *str = "Hello, World!"; char *str = "Hello, World!";
// Plus one for the null terminator // Plus one for the null terminator
char test[strlen(str) + 1]; char test[strlen(str) + 1];
int counter = 0; int counter = 0;
foreach_p(char, item, str, strlen(str) + 1) { foreach(char, item, str, strlen(str) + 1) {
test[counter] = *item; test[counter] = *item;
counter++; counter++;
} }
@ -71,7 +93,7 @@ bool test_simpleString() {
bool test_randomNumbersAsPointers() { bool test_randomNumbersAsPointers() {
int arr1[10]; int arr1[10];
srand(0); srand(0);
foreach_p(int, item, arr1, sizeof(arr1) / sizeof(int)) { foreach(int, item, arr1, sizeof(arr1) / sizeof(int)) {
*item = rand_range(0, 100); *item = rand_range(0, 100);
} }
int arr2[10]; int arr2[10];
@ -90,7 +112,7 @@ bool test_randomNumbersAsPointers() {
bool test_randomNumbersOnHeap() { bool test_randomNumbersOnHeap() {
int *arr1 = malloc(sizeof(int) * 10); int *arr1 = malloc(sizeof(int) * 10);
srand(0); srand(0);
foreach_p(int, item, arr1, 10) { foreach(int, item, arr1, 10) {
*item = rand_range(0, 100); *item = rand_range(0, 100);
} }
int *arr2 = malloc(sizeof(int) * 10); int *arr2 = malloc(sizeof(int) * 10);
@ -110,7 +132,7 @@ bool test_stringOnHeap() {
strcpy(str, "Hello, World!"); strcpy(str, "Hello, World!");
char *test = malloc(sizeof(char) * 14); char *test = malloc(sizeof(char) * 14);
int counter = 0; int counter = 0;
foreach_p(char, item, str, 14) { foreach(char, item, str, 14) {
test[counter] = *item; test[counter] = *item;
counter++; counter++;
} }
@ -122,36 +144,24 @@ bool test_stringOnHeap() {
} }
int main() { int main() {
void* foreach_functions[] = { void* functions[] = {
test_simpleArray, test_simpleArray,
test_randomNumbers, test_randomNumbers,
};
void* foreach_p_functions[] = {
test_simpleString, test_simpleString,
test_randomNumbersAsPointers, test_randomNumbersAsPointers,
test_randomNumbersOnHeap, test_randomNumbersOnHeap,
test_stringOnHeap test_stringOnHeap,
test_twoDimensionalArray,
}; };
printf("foreach tests\n");
printf("Foreach tests\n"); for (int i = 0; i < sizeof(functions) / sizeof(void*); i++) {
for (int i = 0; i < sizeof(foreach_functions) / sizeof(void*); i++) { bool result = ((bool (*)()) functions[i])();
bool result = ((bool (*)()) foreach_functions[i])();
if (result) { if (result) {
printf("Test %d passed\n", i); printf("Test %d passed\n", i);
} else { } else {
printf("Test %d failed\n", i); 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; return EXIT_SUCCESS;
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop