...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::proto::extends — For adding behaviors to a Proto expression template.
// In header: <boost/proto/extends.hpp> template<typename Expr, typename Derived, typename Domain = proto::default_domain> struct extends { // types typedef typename Expr::proto_base_expr proto_base_expr; typedef Domain proto_domain; typedef Derived proto_derived_expr; typedef typename proto_base_expr::proto_tag proto_tag; typedef typename proto_base_expr::proto_args proto_args; typedef typename proto_base_expr::proto_arity proto_arity; typedef typename proto_base_expr::proto_childN
proto_childN; // For eachN
in[0,max(1,proto_arity_c))
// member classes/structs/unions template<typename Signature> struct result { // types typedefunspecified
type; }; // construct/copy/destruct extends(); extends(extends const &); extends(Expr const &); // public static functions static Derived const make(Expr const &); // public member functions proto_base_expr & proto_base(); proto_base_expr const & proto_base() const; template<typename A>unspecified
operator=(A &); template<typename A>unspecified
operator=(A const &); template<typename A>unspecified
operator=(A &) const; template<typename A>unspecified
operator=(A const &) const; template<typename A>unspecified
operator[](A &); template<typename A>unspecified
operator[](A const &); template<typename A>unspecified
operator[](A &) const; template<typename A>unspecified
operator[](A const &) const; template<typename... A>unspecified
operator()(A const &...); template<typename... A>unspecified
operator()(A const &...) const; Expr proto_expr_; // For exposition only. static const long proto_arity_c; //= proto_base_expr::proto_arity_c;
};
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 > { typedef proto::extends< Expr, my_expr< Expr >, my_domain > base_type; // An expression extension is constructed from the expression // it is extending. my_expr( Expr const & e = Expr() ) : base_type( 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:
extends
public
construct/copy/destructextends();
extends(extends const & that);
extends(Expr const & expr_);
extends
public member functionsproto_base_expr & proto_base();
Returns: |
proto_expr_.proto_base() |
Throws: |
Will not throw. |
proto_base_expr const & proto_base() const;
Returns: |
proto_expr_.proto_base() |
Throws: |
Will not throw. |
template<typename A> unspecified
operator=(A & a);
Lazy assignment expression
Returns: |
A new expression node representing the assignment operation. |
template<typename A> unspecified
operator=(A const & a);
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename A> unspecified
operator=(A & a) const;
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename A> unspecified
operator=(A const & a) const;
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename A> unspecified
operator[](A & a);
Lazy subscript expression
Returns: |
A new expression node representing the subscript operation. |
template<typename A> unspecified
operator[](A const & a);
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename A> unspecified
operator[](A & a) const;
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename A> unspecified
operator[](A const & a) const;
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<typename... A> unspecified
operator()(A const &... a);
Lazy function call
Returns: |
A new expression node representing the function call operation. |
template<typename... A> unspecified
operator()(A const &... a) const;
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.