Reputation: 1711
I've got a block in my code in which the for loop should run forwards or backwards depending on a condition.
if (forwards) {
for (unsigned x = 0; x < something.size(); x++ ) {
// Lots of code
}
} else {
for (unsigned x = something.size()-1 ; x >= 0 ; x-- ) {
// Lots of code
}
}
Is there a nice way to set this up, so I don't repeat all the code within the for loop twice?
The 'something' in question is a std::vector<>, so maybe its possible with an iterator? (I'm not using C++11 )
Upvotes: 10
Views: 3692
Reputation: 3002
Or you can do something like this:
for (unsigned x = (forward ? 0: something.size()); x != (forward ? something.size() :0); forward? x++: x-- ) {
// Lots of code
}
The compiler will most likely optimize it and evaluate forward
only once since it's value doesn't change in the for
loop I assume.
Upvotes: 5
Reputation: 14077
template<typename Cont, typename Func>
Func directional_for_each(Cont c, bool forwards, Func f) {
return forwards ? for_each(begin(c), end(c), f) : for_each(rbegin(c), rend(c), f);
}
Used like this:
vector<int> v;
// put stuff in v...
bool forwards = false;
directional_for_each(v, forwards, [](decltype(v[0]) x) {
// Lots of code using x
});
As you're not using C++11 the lambda containing 'Lots of code using x' would have to be replaced with a function defined elsewhere.
Upvotes: 2
Reputation: 29065
Probably the easiest way is to convert Lots of code
to a function with argument x
and replace both loop bodies with a call to that function:
void do_lots_of_stuff(unsigned x) {
// Lots of code
}
////////
if (forwards) {
for (unsigned x = 0; x < something.size(); x++ ) {
do_lots_of_stuff(x);
}
} else {
for (unsigned x = something.size()-1 ; x >= 0 ; x-- ) {
do_lots_of_stuff(x);
}
}
Upvotes: 6
Reputation: 56921
Separate the loop value from the value you use inside the loop:
for (unsigned x2 = 0; x2 < something.size(); x2++ ) {
const int x = forward ? x2 : (something.size()-1) - x2;
// Lots of code using x
}
Upvotes: 17