Created
March 7, 2023 21:23
-
-
Save LukeGary462/ce9d56e1583be067fa5de0496a172490 to your computer and use it in GitHub Desktop.
C foreach macro implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // test | |
| // https://paiza.io/projects/gckklFp-m9gy5nT3pGsFKw | |
| // stack overflow source | |
| // https://stackoverflow.com/questions/400951/does-c-have-a-foreach-loop-construct | |
| #include <stdio.h> | |
| #include <stdint.h> | |
| #define COUNTOF(x) (sizeof(x) / sizeof(x[0])) | |
| #define FOREACH(_item_, _array_) \ | |
| for(size_t i = 0u, _keep_ = 1u; \ | |
| _keep_ && i < COUNTOF(_array_); \ | |
| _keep_ = !_keep_, i++) \ | |
| for (_item_ = _array_[i]; _keep_; _keep_ = !_keep_) | |
| /** test 1 **/ | |
| typedef struct { | |
| unsigned int val; | |
| char *name; | |
| }my_type_t; | |
| my_type_t objList[] = { | |
| {.val=1u, .name="name1"}, | |
| {.val=2u, .name="name2"}, | |
| {.val=3u, .name="name3"}, | |
| {.val=4u, .name="name4"}, | |
| }; | |
| /************/ | |
| /** test 2 **/ | |
| int intArray[] = {-1,0,1,2}; | |
| /************/ | |
| /** test 3 **/ | |
| typedef void ((*module_method_t)(char *argv[], int argc)); | |
| typedef struct { | |
| char *name; | |
| module_method_t method; | |
| } module_obj_t; | |
| void module_method_1(char *argv[], int argc); | |
| void module_method_2(char *argv[], int argc); | |
| void module_method_3(char *argv[], int argc); | |
| void module_method_1(char *argv[], int argc){ | |
| printf("Method 1 execute\n"); | |
| } | |
| void module_method_2(char *argv[], int argc){ | |
| printf("Method 2 execute\n"); | |
| } | |
| void module_method_3(char *argv[], int argc){ | |
| printf("Method 3 execute\n"); | |
| } | |
| module_obj_t moduleList[] = { | |
| {.name="Module 1", .method=module_method_1}, | |
| {.name="Module 2", .method=module_method_2}, | |
| {.name="Module 3", .method=module_method_3}, | |
| }; | |
| /************/ | |
| int main(void){ | |
| printf("Test 1: FOREACH macro with custom data objects ...\n"); | |
| FOREACH(my_type_t item, objList){ | |
| printf("name = %s,\tval = %u\n", | |
| item.name, item.val | |
| ); | |
| } | |
| printf("\nTest 2: FOREACH macro with integer array ...\n"); | |
| FOREACH(int item, intArray){ | |
| printf("value = %d\n", item); | |
| } | |
| printf("\nTest 3: FOREACH macro with list of objects that contain function pointers ...\n"); | |
| FOREACH(module_obj_t item, moduleList){ | |
| printf("Module Name = %s\n\t", item.name); | |
| (void)item.method(NULL, 0); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great.
Would it also be posible to access the index? Something like:
#define FOREACH(_index_, _item_, _array_)I tried it myself, but can't get it to work.