Question
I use macros to code unrolled loops like this: (silly example)
#define foreach_small_prime(p, instr) { \
int p; \
p = 2; instr; \
p = 3; instr; \
p = 5; instr; \
p = 7; instr; \
}
foreach_small_prime(pp, cout << pp);
int sum = 0;
foreach_small_prime(pp, {
sum += pp;
if (sum >= 10) cout << sum << endl;
});
But in some cases I might use for construct:
#define foreach_small_even(ii) for(int ii = 0; ii < 20; ii += 2)
int sum = 0;
foreach_small_even(pp) {
sum += pp;
if (sum >= 10) cout << sum << endl;
}
I like this macros because I can pass a variable name as a parameter.
Question: Is there a way to define loop like the first one in a for-like syntax like the second macro?
Solution
You could check out the Boost preprocessor library. It can do all sorts of looping things. The syntax isn't great, but I believe it works. I have not used it myself, however.
OTHER TIPS
Do you have a good reason to avoid using an iterator object? You have to consider your first macro pastes 4x your instr code...
Otherwise, a simple :
#define foreach_smallprime(ii) for(int ii = 0; ii <= 7; ii = next_prime(ii) )
with next_prime(ii)
defined in the same file as the macro.
Question: Is there a way to define loop like the first one in a for-like syntax like the second macro?
I guess you have a relatively small working-set of prime numbers, so creating a look-up for your primes shouldn't be too troublesome. If you need to generate a larger list of primes, I'm sure there is some compile-time template meta-programming magic available in the Boost library. If you have a more complex series of numbers you're generating it might be wise to turn the lookup into a function that caches the results as they are generated.
const int small_primes[MAX_SMALL_PRIMES] = {2, 3, 5, 7, 11, 13};
#define foreach_small_prime(pp) \
for (int i = 0; i < MAX_SMALL_PRIMES; pp = small_primes[++i])
Used as:
void f() {
int sum = 0;
int temp = 0;
foreach_small_prime(temp) {
sum += temp;
if (sum >= 10) cout << sum << endl;
}
}
Probably want to toss the lookup table and MAX_SMALL_PRIMES theirown namespace to avoid clutter... and using a commonly-used identifier 'i' in the macro is probably a poor choice. I'm sure there are other ways to improve it, but this is fundamentally what you're asking for.