| <?xml version="1.0" encoding="utf-8"?> |
| <!-- |
| Copyright 2012 Eric Niebler |
| |
| Distributed under the Boost |
| Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| --> |
| <header name="boost/proto/transform/impl.hpp"> |
| <para>Contains definition of transform<> and transform_impl<> helpers. </para> |
| <namespace name="boost"> |
| <namespace name="proto"> |
| |
| <!-- proto::transform --> |
| <struct name="transform"> |
| <template> |
| <template-type-parameter name="PrimitiveTransform"/> |
| </template> |
| <purpose>Inherit from this to make your type a <conceptname>PrimitiveTransform</conceptname>.</purpose> |
| <struct-specialization name="result"> |
| <template> |
| <template-type-parameter name="This"/> |
| <template-type-parameter name="Expr"/> |
| </template> |
| <specialization> |
| <template-arg>This(Expr)</template-arg> |
| </specialization> |
| <typedef name="type"> |
| <type>typename PrimitiveTransform::template impl< Expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable> >::result_type</type> |
| </typedef> |
| </struct-specialization> |
| <struct-specialization name="result"> |
| <template> |
| <template-type-parameter name="This"/> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| </template> |
| <specialization> |
| <template-arg>This(Expr, State)</template-arg> |
| </specialization> |
| <typedef name="type"> |
| <type>typename PrimitiveTransform::template impl< Expr, State, <replaceable>unspecified</replaceable> >::result_type</type> |
| </typedef> |
| </struct-specialization> |
| <struct-specialization name="result"> |
| <template> |
| <template-type-parameter name="This"/> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <specialization> |
| <template-arg>This(Expr, State, Data)</template-arg> |
| </specialization> |
| <typedef name="type"> |
| <type>typename PrimitiveTransform::template impl< Expr, State, Data >::result_type</type> |
| </typedef> |
| </struct-specialization> |
| <typedef name="transform_type"> |
| <type>PrimitiveTransform</type> |
| </typedef> |
| <method-group name="public member functions"> |
| <method name="operator()" cv="const"> |
| <type>typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>::result_type</type> |
| <template> |
| <template-type-parameter name="Expr"/> |
| </template> |
| <parameter name="expr"> |
| <paramtype>Expr &</paramtype> |
| </parameter> |
| <returns> |
| <computeroutput> |
| typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>()(expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>) |
| </computeroutput> |
| </returns> |
| </method> |
| <method name="operator()" cv="const"> |
| <type>typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>::result_type</type> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| </template> |
| <parameter name="expr"> |
| <paramtype>Expr &</paramtype> |
| </parameter> |
| <parameter name="state"> |
| <paramtype>State &</paramtype> |
| </parameter> |
| <returns> |
| <computeroutput> |
| typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) |
| </computeroutput> |
| </returns> |
| </method> |
| <method name="operator()" cv="const"> |
| <type>typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>::result_type</type> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| </template> |
| <parameter name="expr"> |
| <paramtype>Expr &</paramtype> |
| </parameter> |
| <parameter name="state"> |
| <paramtype>State const &</paramtype> |
| </parameter> |
| <returns> |
| <computeroutput> |
| typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) |
| </computeroutput> |
| </returns> |
| </method> |
| <method name="operator()" cv="const"> |
| <type>typename PrimitiveTransform::template impl<Expr &, State &, Data &>::result_type</type> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <parameter name="expr"> |
| <paramtype>Expr &</paramtype> |
| </parameter> |
| <parameter name="state"> |
| <paramtype>State &</paramtype> |
| </parameter> |
| <parameter name="data"> |
| <paramtype>Data &</paramtype> |
| </parameter> |
| <returns> |
| <computeroutput> |
| typename PrimitiveTransform::template impl<Expr &, State &, Data &>()(expr, state, data) |
| </computeroutput> |
| </returns> |
| </method> |
| <method name="operator()" cv="const"> |
| <type>typename PrimitiveTransform::template impl<Expr &, State const &, Data &>::result_type</type> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <parameter name="expr"> |
| <paramtype>Expr &</paramtype> |
| </parameter> |
| <parameter name="state"> |
| <paramtype>State const &</paramtype> |
| </parameter> |
| <parameter name="data"> |
| <paramtype>Data &</paramtype> |
| </parameter> |
| <returns> |
| <computeroutput> |
| typename PrimitiveTransform::template impl<Expr &, State const &, Data &>()(expr, state, data) |
| </computeroutput> |
| </returns> |
| </method> |
| </method-group> |
| </struct> |
| |
| <!-- proto::transform_impl --> |
| <struct name="transform_impl"> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <typedef name="expr"> |
| <type>typename boost::remove_reference<Expr const>::type</type> |
| </typedef> |
| <typedef name="expr_param"> |
| <type>typename boost::add_reference<Expr const>::type</type> |
| </typedef> |
| <typedef name="state"> |
| <type>typename boost::remove_reference<State const>::type</type> |
| </typedef> |
| <typedef name="state_param"> |
| <type>typename boost::add_reference<State const>::type</type> |
| </typedef> |
| <typedef name="data"> |
| <type>typename boost::remove_reference<Data const>::type</type> |
| </typedef> |
| <typedef name="data_param"> |
| <type>typename boost::add_reference<Data const>::type</type> |
| </typedef> |
| </struct> |
| |
| <!-- proto::pack --> |
| <struct name="pack"> |
| <purpose>To turn an expression into a pseudo-parameter pack containing the |
| expression's children, for the purpose of expanding the pack expression within |
| a <conceptname>CallableTransform</conceptname> or |
| <conceptname>ObjectTransform</conceptname>.</purpose> |
| <description> |
| <para> |
| <computeroutput>proto::pack</computeroutput> is useful within |
| <conceptname>CallableTransform</conceptname>s and |
| <conceptname>ObjectTransform</conceptname>s when one wishes to unpack an expression |
| into a function call or an object constructor. <computeroutput>proto::pack</computeroutput> |
| turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking |
| pattern to be expanded with the "<computeroutput>...</computeroutput>" syntax. |
| </para> |
| |
| <para> |
| <emphasis role="bold">Example:</emphasis> |
| </para> |
| |
| <para> |
| <programlisting>// The following demonstrates how to use a pseudo-pack expansion |
| // to unpack an expression into a function call. |
| |
| struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname> |
| { |
| typedef int result_type; |
| |
| int operator()(int i) const { return i; } |
| int operator()(int i, int j) const { return i + j; } |
| int operator()(int i, int j, int k) const { return i + j + k; } |
| }; |
| |
| // Take any n-ary expression where the children are all int terminals and sum all the ints |
| struct sum |
| : <classname alt="boost::proto::when">proto::when</classname>< |
| |
| // Match any nary expression where the children are all int terminals |
| <classname alt="boost::proto::nary_expr">proto::nary_expr</classname><<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname><<classname alt="boost::proto::terminal">proto::terminal</classname><int> > > |
| |
| // Turn the current expression into a pseudo-parameter pack, then expand it, |
| // extracting the value from each child in turn. |
| , do_sum(<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))...) |
| > |
| {}; |
| |
| int main() |
| { |
| <classname alt="boost::proto::terminal">proto::terminal</classname><int>::type i = {42}; |
| int result = sum()( i(3,5) ); // Creates a ternary functional-call expression |
| std::cout << "Sum of 42, 3, and 5 : " << result << std::endl; |
| }</programlisting> |
| </para> |
| |
| <para> |
| The above program displays: |
| </para> |
| |
| <para> |
| <computeroutput>Sum of 42, 3, and 5 : 50</computeroutput> |
| </para> |
| |
| <para> |
| In the above example, the type |
| <computeroutput> |
| <classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>)) |
| </computeroutput> |
| is a so-called <emphasis>unpacking pattern</emphasis>, described below. |
| </para> |
| |
| <para> |
| <emphasis role="bold">Unpacking Patterns:</emphasis> |
| </para> |
| |
| <para> |
| Composite transforms (either <conceptname>CallableTransform</conceptname>s or |
| <conceptname>ObjectTransform</conceptname>s) usually have the form |
| <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>. |
| However, when the argument list in a composite transform is terminated with a C-style |
| vararg ellipsis as in <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, |
| the final argument <computeroutput>A<subscript>n</subscript></computeroutput> is treated |
| as an <emphasis>unpacking pattern</emphasis>. |
| </para> |
| |
| <para> |
| An unpacking pattern must itself be a composite transform; that is, it must be a |
| function type representing either a <conceptname>CallableTransform</conceptname> or |
| an <conceptname>ObjectTransform</conceptname>. The type <computeroutput>proto::pack(_)</computeroutput> |
| must appear exactly once in the unpacking pattern. This type will receive a substitution |
| when the unpacking pattern is expanded. |
| </para> |
| |
| <para> |
| A composite transform like <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, |
| when evaluated against a given expression <replaceable>E</replaceable>, state and data, is evaluated as if it were |
| <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n-1</subscript>,<replaceable>S</replaceable>)</computeroutput> |
| where <replaceable>S</replaceable> is a type sequence computed as follows: |
| </para> |
| <para> |
| Let <computeroutput><replaceable>SUB</replaceable>(A,B)</computeroutput> be a type function that replaces every occurence of |
| <computeroutput>proto::pack(_)</computeroutput> within <computeroutput>A</computeroutput> with <computeroutput>B</computeroutput>. |
| <itemizedlist> |
| <listitem> |
| If the expression <replaceable>E</replaceable> is a terminal (i.e. it has arity 0), <replaceable>S</replaceable> |
| is the one-element sequence containing <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_value">proto::_value</classname>)</computeroutput>. |
| </listitem> |
| <listitem> |
| If the expression <replaceable>E</replaceable> is a non-terminal, <replaceable>S</replaceable> is the sequence |
| <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><0>),… |
| <replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><<replaceable>M</replaceable>-1>)</computeroutput>, where |
| <replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>. |
| </listitem> |
| </itemizedlist> |
| </para> |
| </description> |
| </struct> |
| |
| </namespace> |
| </namespace> |
| </header> |