123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- <?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>
|