]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <!-- | |
3 | Copyright 2012 Eric Niebler | |
4 | ||
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) | |
8 | --> | |
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"> | |
13 | ||
14 | <!-- proto::transform --> | |
15 | <struct name="transform"> | |
16 | <template> | |
17 | <template-type-parameter name="PrimitiveTransform"/> | |
18 | </template> | |
19 | <purpose>Inherit from this to make your type a <conceptname>PrimitiveTransform</conceptname>.</purpose> | |
20 | <struct-specialization name="result"> | |
21 | <template> | |
22 | <template-type-parameter name="This"/> | |
23 | <template-type-parameter name="Expr"/> | |
24 | </template> | |
25 | <specialization> | |
26 | <template-arg>This(Expr)</template-arg> | |
27 | </specialization> | |
28 | <typedef name="type"> | |
29 | <type>typename PrimitiveTransform::template impl< Expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable> >::result_type</type> | |
30 | </typedef> | |
31 | </struct-specialization> | |
32 | <struct-specialization name="result"> | |
33 | <template> | |
34 | <template-type-parameter name="This"/> | |
35 | <template-type-parameter name="Expr"/> | |
36 | <template-type-parameter name="State"/> | |
37 | </template> | |
38 | <specialization> | |
39 | <template-arg>This(Expr, State)</template-arg> | |
40 | </specialization> | |
41 | <typedef name="type"> | |
42 | <type>typename PrimitiveTransform::template impl< Expr, State, <replaceable>unspecified</replaceable> >::result_type</type> | |
43 | </typedef> | |
44 | </struct-specialization> | |
45 | <struct-specialization name="result"> | |
46 | <template> | |
47 | <template-type-parameter name="This"/> | |
48 | <template-type-parameter name="Expr"/> | |
49 | <template-type-parameter name="State"/> | |
50 | <template-type-parameter name="Data"/> | |
51 | </template> | |
52 | <specialization> | |
53 | <template-arg>This(Expr, State, Data)</template-arg> | |
54 | </specialization> | |
55 | <typedef name="type"> | |
56 | <type>typename PrimitiveTransform::template impl< Expr, State, Data >::result_type</type> | |
57 | </typedef> | |
58 | </struct-specialization> | |
59 | <typedef name="transform_type"> | |
60 | <type>PrimitiveTransform</type> | |
61 | </typedef> | |
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> | |
65 | <template> | |
66 | <template-type-parameter name="Expr"/> | |
67 | </template> | |
68 | <parameter name="expr"> | |
69 | <paramtype>Expr &</paramtype> | |
70 | </parameter> | |
71 | <returns> | |
72 | <computeroutput> | |
73 | typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>()(expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>) | |
74 | </computeroutput> | |
75 | </returns> | |
76 | </method> | |
77 | <method name="operator()" cv="const"> | |
78 | <type>typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>::result_type</type> | |
79 | <template> | |
80 | <template-type-parameter name="Expr"/> | |
81 | <template-type-parameter name="State"/> | |
82 | </template> | |
83 | <parameter name="expr"> | |
84 | <paramtype>Expr &</paramtype> | |
85 | </parameter> | |
86 | <parameter name="state"> | |
87 | <paramtype>State &</paramtype> | |
88 | </parameter> | |
89 | <returns> | |
90 | <computeroutput> | |
91 | typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) | |
92 | </computeroutput> | |
93 | </returns> | |
94 | </method> | |
95 | <method name="operator()" cv="const"> | |
96 | <type>typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>::result_type</type> | |
97 | <template> | |
98 | <template-type-parameter name="Expr"/> | |
99 | <template-type-parameter name="State"/> | |
100 | </template> | |
101 | <parameter name="expr"> | |
102 | <paramtype>Expr &</paramtype> | |
103 | </parameter> | |
104 | <parameter name="state"> | |
105 | <paramtype>State const &</paramtype> | |
106 | </parameter> | |
107 | <returns> | |
108 | <computeroutput> | |
109 | typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) | |
110 | </computeroutput> | |
111 | </returns> | |
112 | </method> | |
113 | <method name="operator()" cv="const"> | |
114 | <type>typename PrimitiveTransform::template impl<Expr &, State &, Data &>::result_type</type> | |
115 | <template> | |
116 | <template-type-parameter name="Expr"/> | |
117 | <template-type-parameter name="State"/> | |
118 | <template-type-parameter name="Data"/> | |
119 | </template> | |
120 | <parameter name="expr"> | |
121 | <paramtype>Expr &</paramtype> | |
122 | </parameter> | |
123 | <parameter name="state"> | |
124 | <paramtype>State &</paramtype> | |
125 | </parameter> | |
126 | <parameter name="data"> | |
127 | <paramtype>Data &</paramtype> | |
128 | </parameter> | |
129 | <returns> | |
130 | <computeroutput> | |
131 | typename PrimitiveTransform::template impl<Expr &, State &, Data &>()(expr, state, data) | |
132 | </computeroutput> | |
133 | </returns> | |
134 | </method> | |
135 | <method name="operator()" cv="const"> | |
136 | <type>typename PrimitiveTransform::template impl<Expr &, State const &, Data &>::result_type</type> | |
137 | <template> | |
138 | <template-type-parameter name="Expr"/> | |
139 | <template-type-parameter name="State"/> | |
140 | <template-type-parameter name="Data"/> | |
141 | </template> | |
142 | <parameter name="expr"> | |
143 | <paramtype>Expr &</paramtype> | |
144 | </parameter> | |
145 | <parameter name="state"> | |
146 | <paramtype>State const &</paramtype> | |
147 | </parameter> | |
148 | <parameter name="data"> | |
149 | <paramtype>Data &</paramtype> | |
150 | </parameter> | |
151 | <returns> | |
152 | <computeroutput> | |
153 | typename PrimitiveTransform::template impl<Expr &, State const &, Data &>()(expr, state, data) | |
154 | </computeroutput> | |
155 | </returns> | |
156 | </method> | |
157 | </method-group> | |
158 | </struct> | |
159 | ||
160 | <!-- proto::transform_impl --> | |
161 | <struct name="transform_impl"> | |
162 | <template> | |
163 | <template-type-parameter name="Expr"/> | |
164 | <template-type-parameter name="State"/> | |
165 | <template-type-parameter name="Data"/> | |
166 | </template> | |
167 | <typedef name="expr"> | |
168 | <type>typename boost::remove_reference<Expr const>::type</type> | |
169 | </typedef> | |
170 | <typedef name="expr_param"> | |
171 | <type>typename boost::add_reference<Expr const>::type</type> | |
172 | </typedef> | |
173 | <typedef name="state"> | |
174 | <type>typename boost::remove_reference<State const>::type</type> | |
175 | </typedef> | |
176 | <typedef name="state_param"> | |
177 | <type>typename boost::add_reference<State const>::type</type> | |
178 | </typedef> | |
179 | <typedef name="data"> | |
180 | <type>typename boost::remove_reference<Data const>::type</type> | |
181 | </typedef> | |
182 | <typedef name="data_param"> | |
183 | <type>typename boost::add_reference<Data const>::type</type> | |
184 | </typedef> | |
185 | </struct> | |
186 | ||
187 | <!-- proto::pack --> | |
188 | <struct name="pack"> | |
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> | |
193 | <description> | |
194 | <para> | |
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. | |
201 | </para> | |
202 | ||
203 | <para> | |
204 | <emphasis role="bold">Example:</emphasis> | |
205 | </para> | |
206 | ||
207 | <para> | |
208 | <programlisting>// The following demonstrates how to use a pseudo-pack expansion | |
209 | // to unpack an expression into a function call. | |
210 | ||
211 | struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname> | |
212 | { | |
213 | typedef int result_type; | |
214 | ||
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; } | |
218 | }; | |
219 | ||
220 | // Take any n-ary expression where the children are all int terminals and sum all the ints | |
221 | struct sum | |
222 | : <classname alt="boost::proto::when">proto::when</classname>< | |
223 | ||
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> > > | |
226 | ||
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>))...) | |
230 | > | |
231 | {}; | |
232 | ||
233 | int main() | |
234 | { | |
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; | |
238 | }</programlisting> | |
239 | </para> | |
240 | ||
241 | <para> | |
242 | The above program displays: | |
243 | </para> | |
244 | ||
245 | <para> | |
246 | <computeroutput>Sum of 42, 3, and 5 : 50</computeroutput> | |
247 | </para> | |
248 | ||
249 | <para> | |
250 | In the above example, the type | |
251 | <computeroutput> | |
252 | <classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>)) | |
253 | </computeroutput> | |
254 | is a so-called <emphasis>unpacking pattern</emphasis>, described below. | |
255 | </para> | |
256 | ||
257 | <para> | |
258 | <emphasis role="bold">Unpacking Patterns:</emphasis> | |
259 | </para> | |
260 | ||
261 | <para> | |
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>. | |
269 | </para> | |
270 | ||
271 | <para> | |
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. | |
277 | </para> | |
278 | ||
279 | <para> | |
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: | |
284 | </para> | |
285 | <para> | |
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>. | |
288 | <itemizedlist> | |
289 | <listitem> | |
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>. | |
292 | </listitem> | |
293 | <listitem> | |
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>. | |
298 | </listitem> | |
299 | </itemizedlist> | |
300 | </para> | |
301 | </description> | |
302 | </struct> | |
303 | ||
304 | </namespace> | |
305 | </namespace> | |
306 | </header> |