1 <?xml version=
"1.0" encoding=
"utf-8"?>
3 Copyright 2012 Eric Niebler
5 Distributed under the Boost
6 Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 <header name=
"boost/proto/transform/impl.hpp">
10 <para>Contains definition of transform
<> and transform_impl
<> helpers.
</para>
11 <namespace name=
"boost">
12 <namespace name=
"proto">
14 <!-- proto::transform -->
15 <struct name=
"transform">
17 <template-type-parameter name=
"PrimitiveTransform"/>
19 <purpose>Inherit from this to make your type a
<conceptname>PrimitiveTransform
</conceptname>.
</purpose>
20 <struct-specialization name=
"result">
22 <template-type-parameter name=
"This"/>
23 <template-type-parameter name=
"Expr"/>
26 <template-arg>This(Expr)
</template-arg>
29 <type>typename PrimitiveTransform::template impl
< Expr,
<replaceable>unspecified
</replaceable>,
<replaceable>unspecified
</replaceable> >::result_type
</type>
31 </struct-specialization>
32 <struct-specialization name=
"result">
34 <template-type-parameter name=
"This"/>
35 <template-type-parameter name=
"Expr"/>
36 <template-type-parameter name=
"State"/>
39 <template-arg>This(Expr, State)
</template-arg>
42 <type>typename PrimitiveTransform::template impl
< Expr, State,
<replaceable>unspecified
</replaceable> >::result_type
</type>
44 </struct-specialization>
45 <struct-specialization name=
"result">
47 <template-type-parameter name=
"This"/>
48 <template-type-parameter name=
"Expr"/>
49 <template-type-parameter name=
"State"/>
50 <template-type-parameter name=
"Data"/>
53 <template-arg>This(Expr, State, Data)
</template-arg>
56 <type>typename PrimitiveTransform::template impl
< Expr, State, Data
>::result_type
</type>
58 </struct-specialization>
59 <typedef name=
"transform_type">
60 <type>PrimitiveTransform
</type>
62 <method-group name=
"public member functions">
63 <method name=
"operator()" cv=
"const">
64 <type>typename PrimitiveTransform::template impl
<Expr
&,
<replaceable>unspecified
</replaceable>,
<replaceable>unspecified
</replaceable>>::result_type
</type>
66 <template-type-parameter name=
"Expr"/>
68 <parameter name=
"expr">
69 <paramtype>Expr
&</paramtype>
73 typename PrimitiveTransform::template impl
<Expr
&,
<replaceable>unspecified
</replaceable>,
<replaceable>unspecified
</replaceable>>()(expr,
<replaceable>unspecified
</replaceable>,
<replaceable>unspecified
</replaceable>)
77 <method name=
"operator()" cv=
"const">
78 <type>typename PrimitiveTransform::template impl
<Expr
&, State
&,
<replaceable>unspecified
</replaceable>>::result_type
</type>
80 <template-type-parameter name=
"Expr"/>
81 <template-type-parameter name=
"State"/>
83 <parameter name=
"expr">
84 <paramtype>Expr
&</paramtype>
86 <parameter name=
"state">
87 <paramtype>State
&</paramtype>
91 typename PrimitiveTransform::template impl
<Expr
&, State
&,
<replaceable>unspecified
</replaceable>>()(expr, state,
<replaceable>unspecified
</replaceable>)
95 <method name=
"operator()" cv=
"const">
96 <type>typename PrimitiveTransform::template impl
<Expr
&, State const
&,
<replaceable>unspecified
</replaceable>>::result_type
</type>
98 <template-type-parameter name=
"Expr"/>
99 <template-type-parameter name=
"State"/>
101 <parameter name=
"expr">
102 <paramtype>Expr
&</paramtype>
104 <parameter name=
"state">
105 <paramtype>State const
&</paramtype>
109 typename PrimitiveTransform::template impl
<Expr
&, State const
&,
<replaceable>unspecified
</replaceable>>()(expr, state,
<replaceable>unspecified
</replaceable>)
113 <method name=
"operator()" cv=
"const">
114 <type>typename PrimitiveTransform::template impl
<Expr
&, State
&, Data
&>::result_type
</type>
116 <template-type-parameter name=
"Expr"/>
117 <template-type-parameter name=
"State"/>
118 <template-type-parameter name=
"Data"/>
120 <parameter name=
"expr">
121 <paramtype>Expr
&</paramtype>
123 <parameter name=
"state">
124 <paramtype>State
&</paramtype>
126 <parameter name=
"data">
127 <paramtype>Data
&</paramtype>
131 typename PrimitiveTransform::template impl
<Expr
&, State
&, Data
&>()(expr, state, data)
135 <method name=
"operator()" cv=
"const">
136 <type>typename PrimitiveTransform::template impl
<Expr
&, State const
&, Data
&>::result_type
</type>
138 <template-type-parameter name=
"Expr"/>
139 <template-type-parameter name=
"State"/>
140 <template-type-parameter name=
"Data"/>
142 <parameter name=
"expr">
143 <paramtype>Expr
&</paramtype>
145 <parameter name=
"state">
146 <paramtype>State const
&</paramtype>
148 <parameter name=
"data">
149 <paramtype>Data
&</paramtype>
153 typename PrimitiveTransform::template impl
<Expr
&, State const
&, Data
&>()(expr, state, data)
160 <!-- proto::transform_impl -->
161 <struct name=
"transform_impl">
163 <template-type-parameter name=
"Expr"/>
164 <template-type-parameter name=
"State"/>
165 <template-type-parameter name=
"Data"/>
167 <typedef name=
"expr">
168 <type>typename boost::remove_reference
<Expr const
>::type
</type>
170 <typedef name=
"expr_param">
171 <type>typename boost::add_reference
<Expr const
>::type
</type>
173 <typedef name=
"state">
174 <type>typename boost::remove_reference
<State const
>::type
</type>
176 <typedef name=
"state_param">
177 <type>typename boost::add_reference
<State const
>::type
</type>
179 <typedef name=
"data">
180 <type>typename boost::remove_reference
<Data const
>::type
</type>
182 <typedef name=
"data_param">
183 <type>typename boost::add_reference
<Data const
>::type
</type>
189 <purpose>To turn an expression into a pseudo-parameter pack containing the
190 expression's children, for the purpose of expanding the pack expression within
191 a
<conceptname>CallableTransform
</conceptname> or
192 <conceptname>ObjectTransform
</conceptname>.
</purpose>
195 <computeroutput>proto::pack
</computeroutput> is useful within
196 <conceptname>CallableTransform
</conceptname>s and
197 <conceptname>ObjectTransform
</conceptname>s when one wishes to unpack an expression
198 into a function call or an object constructor.
<computeroutput>proto::pack
</computeroutput>
199 turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking
200 pattern to be expanded with the
"<computeroutput>...</computeroutput>" syntax.
204 <emphasis role=
"bold">Example:
</emphasis>
208 <programlisting>// The following demonstrates how to use a pseudo-pack expansion
209 // to unpack an expression into a function call.
211 struct do_sum :
<classname alt=
"boost::proto::callable">proto::callable
</classname>
213 typedef int result_type;
215 int operator()(int i) const { return i; }
216 int operator()(int i, int j) const { return i + j; }
217 int operator()(int i, int j, int k) const { return i + j + k; }
220 // Take any n-ary expression where the children are all int terminals and sum all the ints
222 :
<classname alt=
"boost::proto::when">proto::when
</classname><
224 // Match any nary expression where the children are all int terminals
225 <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
> > >
227 // Turn the current expression into a pseudo-parameter pack, then expand it,
228 // extracting the value from each child in turn.
229 , do_sum(
<classname alt=
"boost::proto::_value">proto::_value
</classname>(proto::pack(
<classname alt=
"boost::proto::_">_
</classname>))...)
235 <classname alt=
"boost::proto::terminal">proto::terminal
</classname><int
>::type i = {
42};
236 int result = sum()( i(
3,
5) ); // Creates a ternary functional-call expression
237 std::cout
<< "Sum of 42, 3, and 5 : " << result
<< std::endl;
242 The above program displays:
246 <computeroutput>Sum of
42,
3, and
5 :
50</computeroutput>
250 In the above example, the type
252 <classname alt=
"boost::proto::_value">proto::_value
</classname>(proto::pack(
<classname alt=
"boost::proto::_">_
</classname>))
254 is a so-called
<emphasis>unpacking pattern
</emphasis>, described below.
258 <emphasis role=
"bold">Unpacking Patterns:
</emphasis>
262 Composite transforms (either
<conceptname>CallableTransform
</conceptname>s or
263 <conceptname>ObjectTransform
</conceptname>s) usually have the form
264 <computeroutput>X(A
<subscript>0</subscript>,…A
<subscript>n
</subscript>)
</computeroutput>.
265 However, when the argument list in a composite transform is terminated with a C-style
266 vararg ellipsis as in
<computeroutput>X(A
<subscript>0</subscript>,…A
<subscript>n
</subscript> ...)
</computeroutput>,
267 the final argument
<computeroutput>A
<subscript>n
</subscript></computeroutput> is treated
268 as an
<emphasis>unpacking pattern
</emphasis>.
272 An unpacking pattern must itself be a composite transform; that is, it must be a
273 function type representing either a
<conceptname>CallableTransform
</conceptname> or
274 an
<conceptname>ObjectTransform
</conceptname>. The type
<computeroutput>proto::pack(_)
</computeroutput>
275 must appear exactly once in the unpacking pattern. This type will receive a substitution
276 when the unpacking pattern is expanded.
280 A composite transform like
<computeroutput>X(A
<subscript>0</subscript>,…A
<subscript>n
</subscript> ...)
</computeroutput>,
281 when evaluated against a given expression
<replaceable>E
</replaceable>, state and data, is evaluated as if it were
282 <computeroutput>X(A
<subscript>0</subscript>,…A
<subscript>n-
1</subscript>,
<replaceable>S
</replaceable>)
</computeroutput>
283 where
<replaceable>S
</replaceable> is a type sequence computed as follows:
286 Let
<computeroutput><replaceable>SUB
</replaceable>(A,B)
</computeroutput> be a type function that replaces every occurence of
287 <computeroutput>proto::pack(_)
</computeroutput> within
<computeroutput>A
</computeroutput> with
<computeroutput>B
</computeroutput>.
290 If the expression
<replaceable>E
</replaceable> is a terminal (i.e. it has arity
0),
<replaceable>S
</replaceable>
291 is the one-element sequence containing
<computeroutput><replaceable>SUB
</replaceable>(A
<subscript>n
</subscript>,
<classname alt=
"boost::proto::_value">proto::_value
</classname>)
</computeroutput>.
294 If the expression
<replaceable>E
</replaceable> is a non-terminal,
<replaceable>S
</replaceable> is the sequence
295 <computeroutput><replaceable>SUB
</replaceable>(A
<subscript>n
</subscript>,
<classname alt=
"boost::proto::_child_c">proto::_child_c
</classname><0>),…
296 <replaceable>SUB
</replaceable>(A
<subscript>n
</subscript>,
<classname alt=
"boost::proto::_child_c">proto::_child_c
</classname><<replaceable>M
</replaceable>-
1>)
</computeroutput>, where
297 <replaceable>M
</replaceable> is the arity of the expression
<replaceable>E
</replaceable>.