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"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -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)

View File

@ -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++)

58
test.c
View File

@ -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