Use:
#include <vector>
#include <cstdio>
using std::printf;
#define FOR(TYPE, IDENT, BEGIN, END) for(TYPE IDENT = BEGIN, IDENT##_end = static_cast<decltype(IDENT)>(END); IDENT < IDENT##_end; ++IDENT)
#define FOR_STEP(TYPE, IDENT, BEGIN, END, STEP) for(TYPE IDENT = (TYPE)(BEGIN), IDENT##_end = static_cast<decltype(IDENT)>(END); IDENT < IDENT##_end; IDENT += STEP )
#define FOR_ITER(IDENT, BEGIN, END) for(auto IDENT = BEGIN, IDENT_end = END; IDENT != IDENT_end; ++IDENT)
int main() {
FOR(int, i, 0, 10) {
printf("FOR i: %d\n", i);
printf("we can even access i_end: %d\n", i_end);
}
FOR(auto, i, 0, 10) {
printf("FOR auto i: %d\n", i);
}
std::vector<int> vec = {4, 5, 7, 2, 3, 1, 4, 9, 8, 6};
printf("FOR with iterator: {");
FOR(auto, it, vec.begin(), vec.end()) {
printf("%d, ", *it);
}
printf("}\n");
printf("FOR with non constant end:\n");
FOR(long, i, 0, vec.size()) {
printf("vec[%ld] = %d\n", i, vec[i]);
}
printf("\n");
// You can set a step size
printf("FOR_STEP(double, d, 0, 20, 2.1): ");
FOR_STEP(double, d, 0, 20, 2.1) {
printf(" %f ", d);
}
printf("\n");
// It works with iterators that don't have "<" but only "!="
// defined, but you probably want to use a range-based 'for' anyway.
printf("FOR_ITER(auto, it, vec.begin(), vec.end()): ");
FOR(auto, it, vec.begin(), vec.end()) {
printf("%d, ", *it);
}
printf("\n");
}
This is the best I could come up with for a C++11 target. It makes sure the END
argument is only evaluated once and requires that begin
and end
have the same type, which is almost always the case.
Since you should not test doubles on equality with an ==
or !=
operator, the default FOR
macros uses an <
operator for comparison, this limits the usage of the macro for iterators, because they now need to have the <
operator defined, too. I could not come up with one solution that works with double and arbitrary iterators alike; you can choose one macro that suits your needs better.
But you should not introduce all of the macros to you code, because with just one macro definition that suits most needs, the code will be much more readable.