4 ms·
I use a slightly different DO macro. For example, DO(count(v)) v[i]=i; DO(3,4) a+=i*10+j; DO(3,4,5) a[i][k]+=b[i][j]*c[j][k]; Where i,j,k are first, sec
by bakul 7y ago
I use a slightly different DO macro. For example,
DO(count(v)) v[i]=i;
DO(3,4) a+=i*10+j;
DO(3,4,5) a[i][k]+=b[i][j]*c[j][k];
Where i,j,k are first, second and third indices. So i in the last example takes values 0..2, for each i value j takes values 0..3 and for each j value k takes values 0..4.
- geocar 7y agoCool! 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++)