I have the following hand-written loop to process parenthesized expressions:
while (!punctuators.empty() && punctuators.back().kind != '(')
{
output.push_back(punctuators.back());
punctuators.pop_back();
}
if (punctuators.empty())
throw invalid_expression(") without matching matching (");
punctuators.pop_back();
(output
and punctuators
are both of type std::vector<token>
, where token
is a very simple struct
that consists of a char kind
and an unsigned value
data member.)
I was wondering if switching from hand-written loops to algorithms would improve readability:
auto p = std::find_if(punctuators.rbegin(), punctuators.rend(),
[](token t){ return t.kind == '('; });
if (p == punctuators.rend())
throw invalid_expression(") without matching matching (");
output.insert(output.end(), punctuators.rbegin(), p);
punctuators.erase(std::prev(p.base()), punctuators.end());
But somehow I feel that this code is a lot less readable, maybe due to the usage of reverse iterators, and especially the conversion to normal iterators. Is there a better solution? Would you agree that the hand-written loop is more readable, or am I simply not seeing the light yet when it comes to algorithms?
You just need the right algorithm.
(untested code)
boost::algorithm::copy_while (
punctuators.rbegin (), punctuators.rend (),
std::back_inserter ( output ),
[](token t){ return t.kind != '('; });
If you're not using boost, you can write copy_while
yourself fairly easily.
There's nothing magical about algorithms; you should get in the habit of writing your own.