4 ms·
Cool! I've often thought about the best way to do this, and your suggestion is compelling. I'm going to try it out.
by geocar 7y ago
Cool!
I've often thought about the best way to do this, and your suggestion is compelling. I'm going to try it out.
- bakul 7y ago:-) The macrology is a bit grody and my DO implementation doesn't extend past 3 args.
- geocar 7y agoI'm interested to know what you think is "grody". This is what I came up with: #define DO(...) for(long long _a[]={__VA_ARGS__,1,1,1,1},i=0;i<*_a;++i) \ for(long long j=0;j<_a[1];++j)for(long long k=0;k<_a[2];++k) It doesn't seem bad to me, and it'd be pretty easy to extend or add asserts to catch when you introduce a fourth arg. gcc also appears smart enough to remove the unnecessary loads, so I'm going to keep playing with it.
- bakul 7y agoClever use of `__VA_ARGS__`! Does gcc remove `_a` as well? Well, may be it was just my implementation: #define mkmacro(func, ...) mkmacro_(func, VA_NUM_ARGS(__VA_ARGS__)) #define mkmacro_(func, nargs) mkmacro__(func, nargs) #define mkmacro__(func, nargs) func ## nargs #define DO(...) mkmacro(DO, __VA_ARGS__)(__VA_ARGS__) #define DO1(n) for(I i=0;i<(n); i++) #define DO2(m,n) DO1(m) for(I j=0;j<(n);j++) #define DO3(l,m,n) DO2(l,m) for(I k=0;k<(n);k++)
- bakul 7y agoI just noticed two missing defines. Sorry about that. Fixed below. I did some testing and seems like this generates much less code at least with clang (with -O3 -fomit-frame-pointer) than geocar's much briefer solution! #define VA_NUM_ARGS(...) \ VA_NUM_ARGS_IMPL(__VA_ARGS__,5,4,3,2,1) #define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N #define mkmacro(func, ...) \ mkmacro_(func, VA_NUM_ARGS(__VA_ARGS__)) #define mkmacro_(func, nargs) mkmacro__(func, nargs) #define mkmacro__(func, nargs) func ## nargs #define DO(...) mkmacro(DO, __VA_ARGS__)(__VA_ARGS__) #define DO1(n) for(I i=0;i<(n); i++) #define DO2(m,n) DO1(m) for(I j=0;j<(n);j++) #define DO3(l,m,n) DO2(l,m) for(I k=0;k<(n);k++)