Last active
May 28, 2024 07:53
-
-
Save m1lkweed/064ff717d38a7959c2861ccb2b9a936c to your computer and use it in GitHub Desktop.
`for each` macro in standard C that works on all types
This file contains 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
#include <stdio.h> | |
// Enhances `for` to automatically iterate over an array. Item cannot be used to modify the contents of array. | |
#if __STDC__ < 202311L | |
#define each(item, ...) \ | |
(int no_loops = 1, break_p = 2; (no_loops >= 1) && (break_p == 2);) \ | |
for(typeof(*(__VA_ARGS__)) *foreach_p = (__VA_ARGS__), *foreach_p2 = foreach_p, (item) = {}; \ | |
(foreach_p < &((foreach_p2)[sizeof(__VA_ARGS__) / sizeof(*(__VA_ARGS__))])) && \ | |
((break_p = (break_p == 2)?0:break_p), no_loops); ++foreach_p) \ | |
if((__builtin_memcpy(&(item), foreach_p, sizeof(item))), 0){}else | |
#else | |
#define each(item, ...) \ | |
(int no_loops = 1, break_p = 2; (no_loops >= 1) && (break_p == 2);) \ | |
for(extern void *memcpy(void *restrict, const void *restrict, typeof(sizeof 0)); (no_loops >= 1) && (break_p == 2);) \ | |
for(typeof(*(__VA_ARGS__)) *foreach_p = (__VA_ARGS__), *foreach_p2 = foreach_p, (item) = {}; \ | |
(foreach_p < &((foreach_p2)[sizeof(__VA_ARGS__) / sizeof(*(__VA_ARGS__))])) && \ | |
((break_p = (break_p == 2)?0:break_p), no_loops); ++foreach_p) \ | |
if((memcpy(&(item), foreach_p, sizeof(item))), 0){}else | |
#endif | |
int main(){ | |
char group[][4] = { | |
"egg", | |
"one", | |
"two", | |
}; | |
for each(x, group){ | |
puts(x); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
corsed