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?

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top