Home | Libraries | People | FAQ | More |
Note | |
---|---|
Note that you can find everything that has been included and defined so far here. |
Let's use sum_items
with
boost::mpl::fold
to build the parser that summarises
the values coming from the + <number>
elements. We can extend the parser
we were using in exp_parser7
by wrapping the repeated
<...>
part with transform
, which transforms
the result of repeated
<...>
with the folding expression
we have just created:
> using exp_parser8 = \ ...> build_parser< \ ...> sequence< \ ...> int_token, /* parse the first <number> */ \ ...> transform< \ ...> repeated<sequence<plus_token, int_token>>, /* parse the "+ <number>" elements */ \ ...> \ ...> /* lambda expression summarising the "+ <number>" elements using fold */ \ ...> boost::mpl::lambda< \ ...> /* The folding expression we have just created */ \ ...> boost::mpl::fold< \ ...> boost::mpl::_1, /* the argument of the lambda expression, the result */ \ ...> /* of the repeated<...> parser */ \ ...> boost::mpl::int_<0>, \ ...> boost::mpl::quote2<sum_items> \ ...> > \ ...> >::type \ ...> > \ ...> > \ ...> >;
It uses transform
to turn the result of the previous version of our parser into one that
summarises the + <number>
elements. Let's try it out:
> exp_parser8::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type boost_::mpl::vector<mpl_::integral_c<int, 1>, mpl_::integral_c<int, 9> >
This returns a pair of numbers as the result of parsing: the first number and the sum of the rest. To get the value of the entire expression we need to add these two numbers together. We can extend our parser to do this final addition as well:
> using exp_parser9 = \ ...> build_parser< \ ...> transform< \ ...> /* What we had so far */ \ ...> sequence< \ ...> int_token, \ ...> transform< \ ...> repeated<sequence<plus_token, int_token>>, \ ...> boost::mpl::lambda< \ ...> boost::mpl::fold< \ ...> boost::mpl::_1, \ ...> boost::mpl::int_<0>, \ ...> boost::mpl::quote2<sum_items> \ ...> > \ ...> >::type \ ...> > \ ...> >, \ ...> boost::mpl::quote1<sum_vector> /* summarise the vector of numbers */ \ ...> > \ ...> >;
exp_parser9
wraps the
parser we had so far (which gives us the two element vector
as the result) with transform
to add the elements of that two element vector
together. Since that two element vector
is a vector
of numbers,
we can (re)use the sum_vector
metafunction for this. Let's try
it out:
> exp_parser9::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type mpl_::integral_c<int, 10>
It gives us the correct result, but it is very inefficient. Let's see why:
There are two loops in this process:
repeated
loops over the input to parse all of the +
<number>
elements. It builds a vector
during this. (Loop 1
on the diagram)
boost::mpl::fold
loops over this vector
to summarise the elements.
(Loop 2
on the diagram)
Note | |
---|---|
Note that we have been talking about loops while there is no such thing as a loop in template metaprogramming. Loops can be implemented using recursion: every recursive call is one iteration of the loop. The loop is stopped at the bottom of the recursive chain. |