Question

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?

Was it helpful?

Solution

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.

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