I want the iterator variable in a for loop to reverse iterate to 0 as an unsigned int
, and I cannot think of a similar comparison to i > -1
, as
Are you really iterating down from some number greater than std::numeric_limits<int>::max()
? If not, I would actually suggest just using a normal int
as your loop variable and static_cast
it to unsigned
in the places in your code that expect it to be unsigned. This way you can use the intuitive >= 0
or > -1
condition and in general I would expect it to be more readable than any of the unsigned alternatives.
The static_cast
would just be to tell the compiler how to operate on the variable and have no performance implications at all.
You can try and define the following macro:
#define for_range(_type, _param, _A1, _B1) \
for (_type _param = _A1, _finish = _B1,\
_step = static_cast<_type>(2*(((int)_finish)>(int)_param)-1),\
_stop = static_cast<_type>(((int)_finish)+(int)_step); _param != _stop; \
_param = static_cast<_type>(((int)_param)+(int)_step))
Now you can use it:
for_range (unsigned, i, 10,0)
{
cout << "backwards i: " << i << endl;
}
It can be used to iterate backwards and forwards through unsigned, integers, enums and chars:
for_range (char, c, 'z','a')
{
cout << c << endl;
}
enum Count { zero, one, two, three };
for_range (Count, c, zero, three)
{
cout << "forward: " << c << endl;
}
Despite its awkward definition it is optimized very well. I looked at disassembler in VC++. The code is extremely efficient. Don't be put off but the three for statements: the compiler will produce only one loop after optimization! You can even define enclosed loops:
unsigned p[4][5];
for_range (Count, i, zero,three)
for_range(unsigned int, j, 4, 0)
{
p[i][j] = static_cast<unsigned>(i)+j;
}
You obviously cannot iterate through enumerated types with gaps.