| <?xml version="1.0" encoding="utf-8"?> |
| <header name="boost/proto/extends.hpp"> |
| <para>Macros and a base class for defining end-user expression types </para> |
| <namespace name="boost"> |
| <namespace name="proto"> |
| |
| <!-- proto::is_proto_expr --> |
| <struct name="is_proto_expr"> |
| <purpose>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.</purpose> |
| <description> |
| <para> |
| <computeroutput>proto::is_proto_expr</computeroutput> allows argument-dependent lookup to find Proto's operator overloads. For example: |
| </para> |
| <para> |
| <programlisting> template<typename T, typename Dummy = <classname>proto::is_proto_expr</classname>> |
| struct my_terminal |
| { |
| <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>( |
| typename <classname>proto::terminal</classname><T>::type |
| , my_terminal<T> |
| , <classname>proto::default_domain</classname> |
| ) |
| }; |
| |
| // ... |
| my_terminal<int> _1, _2; |
| _1 + _2; // OK, uses proto::operator+</programlisting> |
| </para> |
| <para> |
| Without the second <computeroutput>Dummy</computeroutput> template parameter, Proto's operator overloads |
| would not be considered by name lookup. |
| </para> |
| </description> |
| </struct> |
| |
| <!-- proto::extends --> |
| <struct name="extends"> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="Derived"/> |
| <template-type-parameter name="Domain"> |
| <default><classname>proto::default_domain</classname></default> |
| </template-type-parameter> |
| </template> |
| <purpose>For adding behaviors to a Proto expression template.</purpose> |
| <description> |
| <para> |
| Use <computeroutput>proto::extends<></computeroutput> to give expressions in your |
| domain custom data members and member functions. |
| </para> |
| <para> |
| Conceptually, using <computeroutput>proto::extends<></computeroutput> is akin |
| to inheriting from <computeroutput><classname>proto::expr</classname><></computeroutput> |
| and adding your own members. Using <computeroutput>proto::extends<></computeroutput> is |
| generally preferrable to straight inheritance because the members that would be inherited from |
| <computeroutput><classname>proto::expr</classname><></computeroutput> would |
| be wrong; they would incorrectly slice off your additional members when building |
| larger expressions from smaller ones. <computeroutput>proto::extends<></computeroutput> |
| automatically gives your expression types the appropriate operator overloads that |
| preserve your domain-specific members when composing expression trees. |
| </para> |
| <para> |
| Expression extensions are typically defined as follows: |
| </para> |
| <para> |
| <programlisting>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 ... |
| */ |
| };</programlisting> |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| <struct name="result"> |
| <template> |
| <template-type-parameter name="Signature"/> |
| </template> |
| <typedef name="type"> |
| <type><replaceable>unspecified</replaceable></type> |
| </typedef> |
| <description> |
| <para>So that <computeroutput>boost::result_of<></computeroutput> |
| can compute the return type of <computeroutput>proto::extends::operator()</computeroutput>. |
| </para> |
| </description> |
| </struct> |
| <typedef name="proto_base_expr"> |
| <type>typename Expr::proto_base_expr</type> |
| </typedef> |
| <typedef name="proto_domain"> |
| <type>Domain</type> |
| </typedef> |
| <typedef name="proto_derived_expr"> |
| <type>Derived</type> |
| </typedef> |
| <typedef name="proto_tag"> |
| <type>typename proto_base_expr::proto_tag</type> |
| </typedef> |
| <typedef name="proto_args"> |
| <type>typename proto_base_expr::proto_args</type> |
| </typedef> |
| <typedef name="proto_arity"> |
| <type>typename proto_base_expr::proto_arity</type> |
| </typedef> |
| <typedef name="proto_grammar"> |
| <type>typename proto_base_expr::proto_grammar</type> |
| </typedef> |
| <typedef name="proto_childN"> |
| <purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(1,proto_arity_c))</replaceable></purpose> |
| <type>typename proto_base_expr::proto_child<replaceable>N</replaceable></type> |
| </typedef> |
| |
| <!-- constructors --> |
| <constructor/> |
| <constructor> |
| <parameter name="that"> |
| <paramtype><classname>extends</classname> const &</paramtype> |
| </parameter> |
| </constructor> |
| <constructor> |
| <parameter name="expr_"> |
| <paramtype>Expr const &</paramtype> |
| </parameter> |
| </constructor> |
| |
| <method-group name="public static functions"> |
| <method name="make" specifiers="static"> |
| <type>Derived const</type> |
| <parameter name="expr"> |
| <paramtype>Expr const &</paramtype> |
| </parameter> |
| <description> |
| <para>Construct an expression extension from the base expression.</para> |
| </description> |
| <return>Derived(expr)</return> |
| </method> |
| </method-group> |
| |
| <method-group name="public member functions"> |
| |
| <!-- proto_base() --> |
| <method name="proto_base"> |
| <type>proto_base_expr &</type> |
| <returns><computeroutput>proto_expr_.proto_base()</computeroutput></returns> |
| <throws><simpara>Will not throw.</simpara></throws> |
| </method> |
| <method name="proto_base" cv="const"> |
| <type>proto_base_expr const &</type> |
| <returns><computeroutput>proto_expr_.proto_base()</computeroutput></returns> |
| <throws><simpara>Will not throw.</simpara></throws> |
| </method> |
| |
| <!-- operator= --> |
| <method name="operator="> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A &</paramtype> |
| </parameter> |
| <description> |
| <para>Lazy assignment expression</para> |
| </description> |
| <returns> |
| <para>A new expression node representing the assignment operation.</para> |
| </returns> |
| </method> |
| |
| <method name="operator="> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <method name="operator=" cv="const"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <method name="operator=" cv="const"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <!-- operator[] --> |
| <method name="operator[]"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A &</paramtype> |
| </parameter> |
| <description> |
| <para>Lazy subscript expression</para> |
| </description> |
| <returns> |
| <para>A new expression node representing the subscript operation.</para> |
| </returns> |
| </method> |
| |
| <method name="operator[]"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <method name="operator[]" cv="const"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <method name="operator[]" cv="const"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A"/> |
| </template> |
| <parameter name="a"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| |
| <!-- operator() --> |
| <method name="operator()"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A" pack="1"/> |
| </template> |
| <parameter name="a" pack="1"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para>Lazy function call</para> |
| </description> |
| <returns> |
| <para>A new expression node representing the function call operation.</para> |
| </returns> |
| </method> |
| |
| <method name="operator()" cv="const"> |
| <type><replaceable>unspecified</replaceable></type> |
| <template> |
| <template-type-parameter name="A" pack="1"/> |
| </template> |
| <parameter name="a" pack="1"> |
| <paramtype>A const &</paramtype> |
| </parameter> |
| <description> |
| <para> |
| This is an overloaded member function, provided for convenience. It differs from |
| the above function only in what argument(s) it accepts. |
| </para> |
| </description> |
| </method> |
| </method-group> |
| |
| <data-member name="proto_expr_"> |
| <type>Expr</type> |
| <purpose>For exposition only.</purpose> |
| </data-member> |
| |
| <data-member name="proto_arity_c" specifiers="static"> |
| <type>const long</type> |
| <purpose><computeroutput>= proto_base_expr::proto_arity_c;</computeroutput></purpose> |
| </data-member> |
| |
| </struct> |
| |
| </namespace> |
| </namespace> |
| |
| <macro name="BOOST_PROTO_EXTENDS" kind="functionlike"> |
| <macro-parameter name="Expr"/> |
| <macro-parameter name="Derived"/> |
| <macro-parameter name="Domain"/> |
| <purpose>For creating expression wrappers that add behaviors to a Proto expression template, like |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput>, |
| but while retaining POD-ness of the expression wrapper.</purpose> |
| <description> |
| <para> |
| Equivalent to: |
| <programlisting><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>(Expr, Derived, Domain) |
| <macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>() |
| <macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>() |
| <macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</programlisting> |
| </para> |
| <para> |
| <emphasis role="bold">Example:</emphasis><programlisting>template< class Expr > |
| struct my_expr; |
| |
| struct my_domain |
| : <classname alt="boost::proto::domain">proto::domain</classname>< <classname alt="boost::proto::pod_generator">proto::pod_generator</classname>< 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. |
| <macroname>BOOST_PROTO_EXTENDS</macroname>(Expr, my_expr, my_domain) |
| }; |
| |
| // OK, my_expr<> is POD, so this is statically initialized: |
| my_expr< <classname alt="boost::proto::terminal">proto::terminal</classname><int>::type > const _1 = {{1}};</programlisting> |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_BASIC_EXTENDS" kind="functionlike"> |
| <macro-parameter name="Expr"/> |
| <macro-parameter name="Derived"/> |
| <macro-parameter name="Domain"/> |
| <purpose>For creating expression wrappers that add members to a Proto expression template, like |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput>, |
| but while retaining POD-ness of the expression wrapper.</purpose> |
| <description> |
| <para> |
| <computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> adds the basic typedefs, member functions, and |
| data members necessary to make a struct a valid Proto expression extension. It does <emphasis>not</emphasis> |
| add any constructors, virtual functions or access control blocks that would render the containing |
| struct non-POD. |
| </para> |
| <para> |
| <computeroutput>Expr</computeroutput> is the Proto expression that the enclosing struct extends. |
| <computeroutput>Derived</computeroutput> is the type of the enclosing struct. |
| <computeroutput>Domain</computeroutput> is the Proto domain to which this expression extension belongs. |
| (See <computeroutput><classname alt="boost::proto::domain">proto::domain<></classname></computeroutput>.) |
| </para> |
| <para><computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> adds to its enclosing struct |
| exactly one data member of type <computeroutput>Expr</computeroutput>. |
| </para> |
| <para> |
| <emphasis role="bold">Example:</emphasis><programlisting>template< class Expr > |
| struct my_expr; |
| |
| struct my_domain |
| : <classname alt="boost::proto::domain">proto::domain</classname>< <classname alt="boost::proto::pod_generator">proto::pod_generator</classname>< 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. |
| <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>(Expr, my_expr, my_domain) |
| }; |
| |
| // OK, my_expr<> is POD, so this is statically initialized: |
| my_expr< <classname alt="boost::proto::terminal">proto::terminal</classname><int>::type > const _1 = {{1}};</programlisting> |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_EXTENDS_ASSIGN" kind="functionlike"> |
| <purpose>For adding to an expression extension class an overloaded assignment operator that |
| builds an expression template.</purpose> |
| <description> |
| <para> |
| Use <computeroutput>BOOST_PROTO_EXTENDS_ASSIGN()</computeroutput> after <computeroutput> |
| <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression |
| extension class an overloaded assignment operator that builds an expression template. |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_EXTENDS_FUNCTION" kind="functionlike"> |
| <purpose>For adding to an expression extension class a set of overloaded function call operators |
| that build expression templates.</purpose> |
| <description> |
| <para> |
| Use <computeroutput>BOOST_PROTO_EXTENDS_FUNCTION()</computeroutput> after <computeroutput> |
| <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression |
| extension class a set of overloaded function call operators that build expression templates. |
| In addition, <computeroutput>BOOST_PROTO_EXTENDS_FUNCTION()</computeroutput> adds a nested |
| <computeroutput>result<></computeroutput> class template that is a metafunction for |
| calculating the return type of the overloaded function call operators. |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_EXTENDS_SUBSCRIPT" kind="functionlike"> |
| <purpose>For adding to an expression extension class an overloaded subscript operator that |
| builds an expression template.</purpose> |
| <description> |
| <para> |
| Use <computeroutput>BOOST_PROTO_EXTENDS_SUBSCRIPT()</computeroutput> after <computeroutput> |
| <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression |
| extension class an overloaded subscript operator that builds an expression template. |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_EXTENDS_USING_ASSIGN" kind="functionlike"> |
| <macro-parameter name="Derived"/> |
| <purpose>For exposing in classes that inherit from |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| the overloaded assignment operators defined therein.</purpose> |
| <description> |
| <para> |
| The standard usage of |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| is to inherit from it. However, the derived class automatically gets a compiler-generated assignment |
| operator that will hide the ones defined in |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput>. |
| Use <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> in the derived class to unhide the assignment |
| operators defined in |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput>. |
| </para> |
| <para> |
| See <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| for an example that demonstrates usage of <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code>. |
| </para> |
| </description> |
| </macro> |
| |
| <macro name="BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT" kind="functionlike"> |
| <macro-parameter name="Derived"/> |
| <purpose>For exposing in classes that inherit from |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| the overloaded assignment operators defined therein. Unlike the |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput> macro, |
| <code>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()</code> is for use in non-dependent |
| contexts. |
| </purpose> |
| <description> |
| <para> |
| The standard usage of |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| 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 |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput>. |
| Using <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> in the derived class solves this problem. |
| </para> |
| <para> |
| However, if the expression extension is an ordinary class and not a class template, the usage of |
| <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> is in a so-called non-dependent context. In plain English, |
| it means it is illegal to use <code>typename</code> in some places where it is required in a class template. |
| In those cases, you should use <code>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()</code> instead. |
| </para> |
| <para> |
| See also: |
| <itemizedlist> |
| <listitem> |
| <computeroutput><classname alt="boost::proto::extends">proto::extends<></classname></computeroutput> |
| </listitem> |
| <listitem> |
| <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </macro> |
| |
| </header> |