![]() |
Home | Libraries | People | FAQ | More |
The last thing that remains to be done is to tell Proto that it needs
to wrap all of our calculator expressions in our calculator<>
wrapper. We have already wrapped
the placeholders, but we want all expressions that
involve the calculator placeholders to be calculators. We can do that
by specifying an expression generator when we define our calculator_domain
, as follows:
// Define the calculator_domain we forward-declared above. // Specify that all expression in this domain should be wrapped // in the calculator<> expression wrapper. struct calculator_domain : proto::domain< proto::generator< calculator > > {};
The first template parameter to proto::domain<>
is the generator. "Generator"
is just a fancy name for a function object that accepts an expression
and does something to it. proto::generator<>
is a very simple one --- it wraps
an expression in the wrapper you specify. proto::domain<>
inherits from its generator parameter,
so all domains are themselves function objects.
If we used
to keep our expression extension type POD, then we need to use BOOST_PROTO_EXTENDS
()proto::pod_generator<>
instead of proto::generator<>
,
as follows:
// If calculator<> uses BOOST_PROTO_EXTENDS() instead of // use proto::extends<>, use proto::pod_generator<> instead // of proto::generator<>. struct calculator_domain : proto::domain< proto::pod_generator< calculator > > {};
After Proto has calculated a new expression type, it checks the domains
of the child expressions. They must match. Assuming they do, Proto creates
the new expression and passes it to
for any additional processing. If we
don't specify a generator, the new expression gets passed through unchanged.
But since we've specified a generator above, Domain
::operator()calculator_domain::operator()
returns calculator<>
objects.
Now we can use calculator expressions as function objects to STL algorithms, as follows:
double data[] = {1., 2., 3., 4.}; // Use the calculator EDSL to square each element ... WORKS! :-) std::transform( data, data + 4, data, _1 * _1 );