| <?xml version="1.0" encoding="utf-8"?> |
| <header name="boost/proto/transform/when.hpp"> |
| <para> |
| Definition of the |
| <computeroutput> |
| <classname alt="boost::proto::when">proto::when<></classname> |
| </computeroutput> and |
| <computeroutput> |
| <classname alt="boost::proto::otherwise">proto::otherwise<></classname> |
| </computeroutput> transforms. |
| </para> |
| <namespace name="boost"> |
| <namespace name="proto"> |
| <struct name="when"> |
| <template> |
| <template-type-parameter name="Grammar"/> |
| <template-type-parameter name="PrimitiveTransform"> |
| <default>Grammar</default> |
| </template-type-parameter> |
| </template> |
| <purpose>A grammar element and a <conceptname>PrimitiveTransform</conceptname> that associates |
| a transform with the grammar.</purpose> |
| <description> |
| <para> |
| Use <computeroutput>proto::when<></computeroutput> to override a grammar's default |
| transform with a custom transform. It is for used when composing larger transforms by |
| associating smaller transforms with individual rules in your grammar, as in the following |
| transform which counts the number of terminals in an expression. |
| <programlisting>// Count the terminals in an expression tree. |
| // Must be invoked with initial state == mpl::int_<0>(). |
| struct CountLeaves : |
| <classname>proto::or_</classname>< |
| proto::when<<classname>proto::terminal</classname><<classname>proto::_</classname>>, mpl::next<<classname>proto::_state</classname>>()>, |
| proto::otherwise<<classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves> > |
| > |
| {};</programlisting> |
| </para> |
| <para> |
| In <computeroutput>proto::when<G, T></computeroutput>, when <computeroutput>T</computeroutput> |
| is a class type it is a <conceptname>PrimitiveTransform</conceptname> and the following equivalencies hold: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| <computeroutput>boost::result_of<proto::when<G,T>(E,S,V)>::type</computeroutput> is the same as |
| <computeroutput>boost::result_of<T(E,S,V)>::type</computeroutput>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <computeroutput>proto::when<G,T>()(e,s,d)</computeroutput> is the same as |
| <computeroutput>T()(e,s,d)</computeroutput>. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </description> |
| <inherit><type>PrimitiveTransform</type></inherit> |
| <typedef name="proto_grammar"> |
| <type>typename Grammar::proto_grammar</type> |
| </typedef> |
| </struct> |
| |
| <struct-specialization name="when"> |
| <template> |
| <template-type-parameter name="Grammar"/> |
| <template-type-parameter name="Fun"/> |
| </template> |
| <specialization> |
| <template-arg>Grammar</template-arg> |
| <template-arg>Fun *</template-arg> |
| </specialization> |
| <inherit><classname>proto::when</classname>< Grammar, Fun ></inherit> |
| <purpose>A specialization that treats function pointer <conceptname>Transform</conceptname>s as if they |
| were function type <conceptname>Transform</conceptname>s.</purpose> |
| <description> |
| <para> |
| This specialization requires that <computeroutput>Fun</computeroutput> is actually a function type. |
| </para> |
| <para> |
| This specialization is required for nested transforms such as |
| <computeroutput>proto::when<G, T0(T1(_))></computeroutput>. In C++, functions that are used |
| as parameters to other functions automatically decay to funtion pointer types. In other words, the |
| type <computeroutput>T0(T1(_))</computeroutput> is indistinguishable from |
| <computeroutput>T0(T1(*)(_))</computeroutput>. This specialization is required to handle these |
| nested function pointer type transforms properly. |
| </para> |
| </description> |
| </struct-specialization> |
| |
| <struct-specialization name="when"> |
| <template> |
| <template-type-parameter name="Grammar"/> |
| <template-type-parameter name="R"/> |
| <template-type-parameter name="A" pack="1"/> |
| </template> |
| <specialization> |
| <template-arg>Grammar</template-arg> |
| <template-arg>R(A...)</template-arg> |
| </specialization> |
| <inherit><classname>proto::transform</classname>< when<Grammar, R(A...)> ></inherit> |
| <purpose>A grammar element and a <conceptname>PrimitiveTransform</conceptname> that associates a |
| transform with the grammar. </purpose> |
| <description> |
| <para> |
| Use <computeroutput>proto::when<></computeroutput> to override a grammar's default |
| transform with a custom transform. It is for use when composing larger transforms by associating |
| smaller transforms with individual rules in your grammar. |
| </para> |
| <para> |
| The <computeroutput>when<G, R(A...)></computeroutput> form accepts either a |
| <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its |
| second parameter. <computeroutput>proto::when<></computeroutput> uses |
| <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> to |
| distinguish between the two, and uses |
| <computeroutput><classname>proto::call<></classname></computeroutput> to evaluate |
| <conceptname>CallableTransform</conceptname>s and |
| <computeroutput><classname>proto::make<></classname></computeroutput> to evaluate |
| <conceptname>ObjectTransform</conceptname>s. |
| </para> |
| </description> |
| <struct name="impl"> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <inherit><classname>proto::transform_impl</classname>< Expr, State, Data ></inherit> |
| <typedef name="call_"> |
| <purpose>For exposition only</purpose> |
| <type><classname>proto::call</classname><R(A...)></type> |
| </typedef> |
| <typedef name="make_"> |
| <purpose>For exposition only</purpose> |
| <type><classname>proto::make</classname><R(A...)></type> |
| </typedef> |
| <typedef name="which"> |
| <purpose>For exposition only</purpose> |
| <type>typename mpl::if_<<classname>proto::is_callable</classname><R>,call_,make_>::type</type> |
| </typedef> |
| <typedef name="result_type"> |
| <type>typename boost::result_of<which(Expr, State, Data)>::type</type> |
| </typedef> |
| <method-group name="public member functions"> |
| <method name="operator()" cv="const"> |
| <type>result_type</type> |
| <parameter name="expr"> |
| <paramtype>typename impl::expr_param</paramtype> |
| <description> |
| <para>The current expression </para> |
| </description> |
| </parameter> |
| <parameter name="state"> |
| <paramtype>typename impl::state_param</paramtype> |
| <description> |
| <para>The current state </para> |
| </description> |
| </parameter> |
| <parameter name="data"> |
| <paramtype>typename impl::data_param</paramtype> |
| <description> |
| <para>An arbitrary data </para> |
| </description> |
| </parameter> |
| <description> |
| <para> |
| Evaluate <computeroutput>R(A...)</computeroutput> as a transform either with |
| <computeroutput><classname>proto::call<></classname></computeroutput> or with |
| <computeroutput><classname>proto::make<></classname></computeroutput> depending |
| on whether <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> |
| is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>. |
| </para> |
| </description> |
| <requires> |
| <para> |
| <computeroutput><classname>proto::matches</classname><Expr, Grammar>::value</computeroutput> |
| is <computeroutput>true</computeroutput>. |
| </para> |
| </requires> |
| <returns> |
| <para> |
| <computeroutput>which()(expr, state, data)</computeroutput> |
| </para> |
| </returns> |
| </method> |
| </method-group> |
| </struct> |
| <typedef name="proto_grammar"> |
| <type>typename Grammar::proto_grammar</type> |
| </typedef> |
| </struct-specialization> |
| |
| <struct name="otherwise"> |
| <template> |
| <template-type-parameter name="Fun"/> |
| </template> |
| <inherit><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></inherit> |
| <purpose> |
| Syntactic sugar for <computeroutput><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></computeroutput>, |
| for use in grammars to handle all the cases not yet handled. |
| </purpose> |
| <description> |
| <para> |
| Use <computeroutput>proto::otherwise<T></computeroutput> in your grammars as a synonym for |
| <computeroutput><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></computeroutput> |
| as in the following transform which counts the number of terminals in an expression. |
| </para> |
| <para> |
| <programlisting>// Count the terminals in an expression tree. |
| // Must be invoked with initial state == mpl::int_<0>(). |
| struct CountLeaves : |
| <classname>proto::or_</classname>< |
| proto::when<<classname>proto::terminal</classname><<classname>proto::_</classname>>, mpl::next<<classname>proto::_state</classname>>()>, |
| proto::otherwise<<classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves> > |
| > |
| {};</programlisting> |
| </para> |
| </description> |
| </struct> |
| </namespace> |
| </namespace> |
| </header> |