Macros and a base class for defining end-user expression types
Empty type to be used as a dummy template parameter of POD expression wrappers. It allows
argument-dependent lookup to find Proto's operator overloads.
proto::is_proto_expr allows argument-dependent lookup to find Proto's operator overloads. For example:
template<typename T, typename Dummy = proto::is_proto_expr>
struct my_terminal
{
BOOST_PROTO_BASIC_EXTENDS(
typename proto::terminal<T>::type
, my_terminal<T>
, proto::default_domain
)
};
// ...
my_terminal<int> _1, _2;
_1 + _2; // OK, uses proto::operator+
Without the second Dummy template parameter, Proto's operator overloads
would not be considered by name lookup.
proto::default_domain
For adding behaviors to a Proto expression template.
Use proto::extends<> to give expressions in your
domain custom data members and member functions.
Conceptually, using proto::extends<> is akin
to inheriting from proto::expr<>
and adding your own members. Using proto::extends<> is
generally preferrable to straight inheritance because the members that would be inherited from
proto::expr<> would
be wrong; they would incorrectly slice off your additional members when building
larger expressions from smaller ones. proto::extends<>
automatically gives your expression types the appropriate operator overloads that
preserve your domain-specific members when composing expression trees.
Expression extensions are typically defined as follows:
template< typename Expr >
struct my_expr
: proto::extends<
Expr // The expression type we're extending
, my_expr< Expr > // The type we're defining
, my_domain // The domain associated with this expression extension
>
{
// An expression extension is constructed from the expression
// it is extending.
my_expr( Expr const & e = Expr() )
: my_expr::proto_extends( e )
{}
// Unhide proto::extends::operator=
// (This is only necessary if a lazy assignment operator
// makes sense for your domain-specific language.)
BOOST_PROTO_EXTENDS_USING_ASSIGN(my_expr)
/*
... domain-specific members go here ...
*/
};
See also:
BOOST_PROTO_EXTENDS()
BOOST_PROTO_EXTENDS_USING_ASSIGN()
BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()
unspecified
So that boost::result_of<>
can compute the return type of proto::extends::operator().
typename Expr::proto_base_expr
Domain
Derived
extends
typename proto_base_expr::proto_tag
typename proto_base_expr::proto_args
typename proto_base_expr::proto_arity
typename proto_base_expr::proto_grammar
For each N in [0,max(1,proto_arity_c))
typename proto_base_expr::proto_childN
extends const &
Expr const &
Derived const
Expr const &
Construct an expression extension from the base expression.
Derived(expr)
proto_base_expr &
proto_expr_.proto_base()
Will not throw.
proto_base_expr const &
proto_expr_.proto_base()
Will not throw.
unspecified
A &
Lazy assignment expression
A new expression node representing the assignment operation.
unspecified
A const &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A const &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A &
Lazy subscript expression
A new expression node representing the subscript operation.
unspecified
A const &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A const &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
unspecified
A const &
Lazy function call
A new expression node representing the function call operation.
unspecified
A const &
This is an overloaded member function, provided for convenience. It differs from
the above function only in what argument(s) it accepts.
Expr
For exposition only.
const long
= proto_base_expr::proto_arity_c;
For creating expression wrappers that add behaviors to a Proto expression template, like
proto::extends<>,
but while retaining POD-ness of the expression wrapper.
Equivalent to:
BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain)
BOOST_PROTO_EXTENDS_ASSIGN()
BOOST_PROTO_EXTENDS_SUBSCRIPT()
BOOST_PROTO_EXTENDS_FUNCTION()
If the Domain parameter is dependent, you can specify it as
typename Domain, as in
BOOST_PROTO_EXTENDS(Expr, Derived, typename Domain)
Example:template< class Expr >
struct my_expr;
struct my_domain
: proto::domain< proto::pod_generator< my_expr > >
{};
template< class Expr >
struct my_expr
{
// OK, this makes my_expr<> a valid Proto expression extension.
// my_expr<> has overloaded assignment, subscript,
// and function call operators that build expression templates.
BOOST_PROTO_EXTENDS(Expr, my_expr, my_domain)
};
// OK, my_expr<> is POD, so this is statically initialized:
my_expr< proto::terminal<int>::type > const _1 = {{1}};
For creating expression wrappers that add members to a Proto expression template, like
proto::extends<>,
but while retaining POD-ness of the expression wrapper.
BOOST_PROTO_BASIC_EXTENDS() adds the basic typedefs, member functions, and
data members necessary to make a struct a valid Proto expression extension. It does not
add any constructors, virtual functions or access control blocks that would render the containing
struct non-POD.
Expr is the Proto expression that the enclosing struct extends.
Derived is the type of the enclosing struct.
Domain is the Proto domain to which this expression extension belongs.
(See proto::domain<>.)
Can be preceeded with "typename" if the specified domain is a dependent type.
BOOST_PROTO_BASIC_EXTENDS() adds to its enclosing struct
exactly one data member of type Expr.
If the Domain parameter is dependent, you can specify it as
typename Domain, as in
BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, typename Domain)
Example:template< class Expr >
struct my_expr;
struct my_domain
: proto::domain< proto::pod_generator< my_expr > >
{};
template< class Expr >
struct my_expr
{
// OK, this makes my_expr<> a valid Proto expression extension.
// my_expr<> does /not/ have overloaded assignment, subscript,
// and function call operators that build expression templates, however.
BOOST_PROTO_BASIC_EXTENDS(Expr, my_expr, my_domain)
};
// OK, my_expr<> is POD, so this is statically initialized:
my_expr< proto::terminal<int>::type > const _1 = {{1}};
See also:
BOOST_PROTO_EXTENDS_ASSIGN()
BOOST_PROTO_EXTENDS_SUBSCRIPT()
BOOST_PROTO_EXTENDS_FUNCTION()
BOOST_PROTO_EXTENDS()
For adding to an expression extension class an overloaded assignment operator that
builds an expression template.
Use BOOST_PROTO_EXTENDS_ASSIGN() after
BOOST_PROTO_BASIC_EXTENDS() to give an expression
extension class an overloaded assignment operator that builds an expression template.
See also:
BOOST_PROTO_BASIC_EXTENDS()
BOOST_PROTO_EXTENDS_SUBSCRIPT()
BOOST_PROTO_EXTENDS_FUNCTION()
BOOST_PROTO_EXTENDS()
For adding to an expression extension class a set of overloaded function call operators
that build expression templates.
Use BOOST_PROTO_EXTENDS_FUNCTION() after
BOOST_PROTO_BASIC_EXTENDS() to give an expression
extension class a set of overloaded function call operators that build expression templates.
In addition, BOOST_PROTO_EXTENDS_FUNCTION() adds a nested
result<> class template that is a metafunction for
calculating the return type of the overloaded function call operators.
See also:
BOOST_PROTO_BASIC_EXTENDS()
BOOST_PROTO_EXTENDS_ASSIGN()
BOOST_PROTO_EXTENDS_SUBSCRIPT()
BOOST_PROTO_EXTENDS()
For adding to an expression extension class an overloaded subscript operator that
builds an expression template.
Use BOOST_PROTO_EXTENDS_SUBSCRIPT() after
BOOST_PROTO_BASIC_EXTENDS() to give an expression
extension class an overloaded subscript operator that builds an expression template.
See also:
BOOST_PROTO_BASIC_EXTENDS()
BOOST_PROTO_EXTENDS_ASSIGN()
BOOST_PROTO_EXTENDS_FUNCTION()
BOOST_PROTO_EXTENDS()
For exposing in classes that inherit from
proto::extends<>
the overloaded assignment operators defined therein.
The standard usage of
proto::extends<>
is to inherit from it. However, the derived class automatically gets a compiler-generated assignment
operator that will hide the ones defined in
proto::extends<>.
Use BOOST_PROTO_EXTENDS_USING_ASSIGN()
in the derived class to unhide the assignment
operators defined in
proto::extends<>.
See proto::extends<>
for an example that demonstrates usage of BOOST_PROTO_EXTENDS_USING_ASSIGN()
.
For exposing in classes that inherit from
proto::extends<>
the overloaded assignment operators defined therein. Unlike the
BOOST_PROTO_EXTENDS_USING_ASSIGN() macro,
BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()
is for use in non-dependent
contexts.
The standard usage of
proto::extends<>
is to define a class template that inherits from it. The derived class template automatically gets a
compiler-generated assignment operator that hides the ones defined in
proto::extends<>.
Using BOOST_PROTO_EXTENDS_USING_ASSIGN()
in the derived class solves this problem.
However, if the expression extension is an ordinary class and not a class template, the usage of
BOOST_PROTO_EXTENDS_USING_ASSIGN()
is in a so-called non-dependent context. In plain English,
it means it is illegal to use typename
in some places where it is required in a class template.
In those cases, you should use BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()
instead.
See also:
proto::extends<>
BOOST_PROTO_EXTENDS_USING_ASSIGN()