![]() |
Home | Libraries | People | FAQ | More |
The preceding discussions of defining Proto front ends have all made a
big assumption: that you have the luxury of defining everything from scratch.
What happens if you have existing types, say a matrix type and a vector
type, that you would like to treat as if they were Proto terminals? Proto
usually trades only in its own expression types, but with
,
it can accomodate your custom terminal types, too.
BOOST_PROTO_DEFINE_OPERATORS
()
Let's say, for instance, that you have the following types and that you can't modify then to make them “native” Proto terminal types.
namespace math { // A matrix type ... struct matrix { /*...*/ }; // A vector type ... struct vector { /*...*/ }; }
You can non-intrusively make objects of these types Proto terminals by
defining the proper operator overloads using
.
The basic procedure is as follows:
BOOST_PROTO_DEFINE_OPERATORS
()
BOOST_PROTO_DEFINE_OPERATORS
()
to define a set of operator overloads, passing the name of the trait
as the first macro parameter, and the name of a Proto domain (e.g.,
proto::default_domain
)
as the second.
The following code demonstrates how it works.
namespace math { template<typename T> struct is_terminal : mpl::false_ {}; // OK, "matrix" is a custom terminal type template<> struct is_terminal<matrix> : mpl::true_ {}; // OK, "vector" is a custom terminal type template<> struct is_terminal<vector> : mpl::true_ {}; // Define all the operator overloads to construct Proto // expression templates, treating "matrix" and "vector" // objects as if they were Proto terminals. BOOST_PROTO_DEFINE_OPERATORS(is_terminal, proto::default_domain) }
The invocation of the
macro defines a complete set of operator overloads that treat BOOST_PROTO_DEFINE_OPERATORS
()matrix
and vector
objects as if they were Proto terminals. And since the operators are defined
in the same namespace as the matrix
and vector
types, the operators
will be found by argument-dependent lookup. With the code above, we can
now construct expression templates with matrices and vectors, as shown
below.
math::matrix m1; math::vector v1; proto::literal<int> i(0); m1 * 1; // custom terminal and literals are OK m1 * i; // custom terminal and Proto expressions are OK m1 * v1; // two custom terminals are OK, too.