]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/doc/reference/transform/make.xml
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / proto / doc / reference / transform / make.xml
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/make.hpp">
10 <para>
11 Contains definition of the
12 <computeroutput>
13 <classname alt="boost::proto::make">proto::make&lt;&gt;</classname>
14 </computeroutput>
15 and
16 <computeroutput>
17 <classname alt="boost::proto::protect">proto::protect&lt;&gt;</classname>
18 </computeroutput>
19 transforms.
20 </para>
21 <namespace name="boost">
22 <namespace name="proto">
23 <struct name="noinvoke">
24 <template>
25 <template-type-parameter name="T"/>
26 </template>
27 <purpose>A type annotation in an <conceptname>ObjectTransform</conceptname> which instructs
28 Proto not to look for a nested <computeroutput>::type</computeroutput> within
29 <computeroutput>T</computeroutput> after type substitution.</purpose>
30 <description>
31 <para>
32 <conceptname>ObjectTransform</conceptname>s are evaluated by
33 <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>,
34 which finds all nested transforms and replaces them with the result of their applications.
35 If any substitutions are performed, the result is first assumed to be a metafunction to be applied;
36 that is, Proto checks to see if the result has a nested <computeroutput>::type</computeroutput>
37 typedef. If it does, that becomes the result. The purpose of <computeroutput>proto::noinvoke&lt;&gt;</computeroutput>
38 is to prevent Proto from looking for a nested <computeroutput>::type</computeroutput> typedef
39 in these situations.
40 </para>
41 <para>
42 Example:
43 <programlisting>struct Test
44 : <classname>proto::when</classname>&lt;
45 <classname>_</classname>
46 , proto::noinvoke&lt;
47 // This remove_pointer invocation is bloked by noinvoke
48 boost::remove_pointer&lt;
49 // This add_pointer invocation is *not* blocked by noinvoke
50 boost::add_pointer&lt;<classname>_</classname>&gt;
51 &gt;
52 &gt;()
53 &gt;
54 {};
55
56 void test_noinvoke()
57 {
58 typedef <classname>proto::terminal</classname>&lt;int&gt;::type Int;
59
60 BOOST_MPL_ASSERT((
61 boost::is_same&lt;
62 boost::result_of&lt;Test(Int)&gt;::type
63 , boost::remove_pointer&lt;Int *&gt;
64 &gt;
65 ));
66
67 Int i = {42};
68 boost::remove_pointer&lt;Int *&gt; t = Test()(i);
69 }</programlisting>
70 </para>
71 </description>
72 </struct>
73 <struct name="protect">
74 <template>
75 <template-type-parameter name="PrimitiveTransform"/>
76 </template>
77 <inherit><classname>proto::transform</classname>&lt; protect&lt;PrimitiveTransform&gt; &gt;</inherit>
78 <purpose>A <conceptname>PrimitiveTransform</conceptname> which prevents another
79 <conceptname>PrimitiveTransform</conceptname> from being applied in an
80 <conceptname>ObjectTransform</conceptname>.</purpose>
81 <description>
82 <para>
83 When building higher order transforms with
84 <computeroutput>
85 <classname alt="proto::make">proto::make&lt;&gt;</classname>
86 </computeroutput> or
87 <computeroutput>
88 <classname alt="proto::lazy">proto::lazy&lt;&gt;</classname>
89 </computeroutput>,
90 you sometimes would like to build types that are parameterized with Proto transforms. In such
91 lambda-style transforms, Proto will unhelpfully find all nested transforms and apply them, even
92 if you don't want them to be applied. Consider the following transform, which will replace the
93 <computeroutput>proto::_</computeroutput> in
94 <computeroutput>Bar&lt;proto::_&gt;()</computeroutput>
95 with <computeroutput>proto::terminal&lt;int&gt;::type</computeroutput>:
96 </para>
97 <para>
98 <programlisting>template&lt;typename T&gt;
99 struct Bar
100 {};
101
102 struct Foo :
103 <classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::_</classname>&gt;() &gt;
104 {};
105
106 <classname>proto::terminal</classname>&lt;int&gt;::type i = {0};
107
108 int main() {
109 Foo()(i);
110 std::cout &lt;&lt; typeid(Foo()(i)).name() &lt;&lt; std::endl;
111 }</programlisting>
112 </para>
113 <para>
114 If you actually wanted to default-construct an object of type
115 <computeroutput>Bar&lt;proto::_&gt;</computeroutput>, you would have to protect the
116 <computeroutput>_</computeroutput> to prevent it from being applied. You can
117 use <computeroutput>proto::protect&lt;&gt;</computeroutput> as follows:
118 </para>
119 <para>
120 <programlisting>// OK: replace anything with Bar&lt;_&gt;()
121 struct Foo :
122 <classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::protect</classname>&lt;<classname>proto::_</classname>&gt; &gt;() &gt;
123 {};</programlisting>
124 </para>
125 </description>
126 <struct name="impl">
127 <template>
128 <template-type-parameter name=""/>
129 <template-type-parameter name=""/>
130 <template-type-parameter name=""/>
131 </template>
132 <typedef name="result_type">
133 <type>PrimitiveTransform</type>
134 </typedef>
135 </struct>
136 </struct>
137
138 <struct name="make">
139 <template>
140 <template-type-parameter name="T"/>
141 </template>
142
143 <inherit><classname>proto::transform</classname>&lt; make&lt;T&gt; &gt;</inherit>
144
145 <purpose>A <conceptname>PrimitiveTransform</conceptname> that computes a type by evaluating
146 any nested transforms and then constructs an object of that type. </purpose>
147
148 <description>
149 <para>
150 The purpose of <computeroutput>proto::make&lt;&gt;</computeroutput> is to annotate a transform as
151 an <conceptname>ObjectTransform</conceptname> so that
152 <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> knows
153 how to apply it.
154 </para>
155
156 <para>
157 For the full description of the behavior of the
158 <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>
159 transform, see the documentation for the nested
160 <computeroutput><classname alt="proto::make::impl">proto::make::impl&lt;&gt;</classname></computeroutput>
161 class template.
162 </para>
163 </description>
164
165 <struct name="impl">
166 <template>
167 <template-type-parameter name="Expr"/>
168 <template-type-parameter name="State"/>
169 <template-type-parameter name="Data"/>
170 </template>
171 <inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
172 <typedef name="result_type">
173 <type><emphasis>see-below</emphasis></type>
174 <description>
175 <para>
176 <computeroutput><classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr, State, Data&gt;::result_type</computeroutput> is
177 computed as follows:
178 </para>
179 <para>
180 If <computeroutput>T</computeroutput> is an <conceptname>ObjectTransform</conceptname> of the form
181 <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput> or
182 <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
183 then let <computeroutput>O</computeroutput> be the return type
184 <computeroutput>Object</computeroutput>. Otherwise, let <computeroutput>O</computeroutput>
185 be <computeroutput>T</computeroutput>. The <computeroutput>result_type</computeroutput> typedef is
186 then computed as follows:
187 </para>
188 <para>
189 <itemizedlist>
190 <listitem>
191 <para>
192 If <computeroutput><classname>proto::is_transform</classname>&lt;O&gt;::value</computeroutput> is
193 <computeroutput>true</computeroutput>, then let the result type be
194 <computeroutput>
195 boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>_</classname>, O&gt;(Expr, State, Data)&gt;::type
196 </computeroutput>.
197 Note that a substitution took place.
198 </para>
199 </listitem>
200 <listitem>
201 If <computeroutput>O</computeroutput> is a template like
202 <computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt; &gt;</computeroutput>,
203 then the result type is calculated as follows:
204 <itemizedlist>
205 <listitem>
206 <para>
207 For each <computeroutput>i</computeroutput> in
208 <computeroutput>[0,n]</computeroutput>, let <computeroutput>
209 X<subscript>i</subscript>'
210 </computeroutput> be
211 <computeroutput>
212 boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
213 </computeroutput>
214 (which evaluates this procedure recursively). Note that a substitution took place. (In this case,
215 Proto merely assumes that a substitution took place for the sake of compile-time efficiency. There
216 would be no reason to use <computeroutput><classname>proto::noinvoke&lt;&gt;</classname></computeroutput>
217 otherwise.)
218 </para>
219 </listitem>
220 <listitem>
221 <para>
222 The result type is
223 <computeroutput>
224 S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
225 </computeroutput>.
226 </para>
227 </listitem>
228 </itemizedlist>
229 </listitem>
230 <listitem>
231 If <computeroutput>O</computeroutput> is a template like
232 <computeroutput>S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt;</computeroutput>,
233 then the result type is calculated as follows:
234 <itemizedlist>
235 <listitem>
236 <para>
237 For each <computeroutput>i</computeroutput> in
238 <computeroutput>[0,n]</computeroutput>, let <computeroutput>
239 X<subscript>i</subscript>'
240 </computeroutput> be
241 <computeroutput>
242 boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
243 </computeroutput>
244 (which evaluates this procedure recursively). Note whether any substitutions took place during
245 this operation.
246 </para>
247 </listitem>
248 <listitem>
249 <para>
250 If any substitutions took place in the above step and
251 <computeroutput>
252 S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
253 </computeroutput> has a nested
254 <computeroutput>type</computeroutput> typedef, the result type is
255 <computeroutput>
256 S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;::type
257 </computeroutput>.
258 </para>
259 </listitem>
260 <listitem>
261 <para>
262 Otherwise, the result type is
263 <computeroutput>
264 S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
265 </computeroutput>.
266 </para>
267 </listitem>
268 </itemizedlist>
269 </listitem>
270 <listitem>
271 Otherwise, the result type is <computeroutput>O</computeroutput>, and note that no
272 substitution took place.
273 </listitem>
274 </itemizedlist>
275 </para>
276 <para>
277 Note that <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> is implemented
278 in terms of <computeroutput><classname alt="proto::call">proto::call&lt;&gt;</classname></computeroutput>
279 and <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>, so the
280 above procedure is evaluated recursively.
281 </para>
282 </description>
283 </typedef>
284 <method-group name="public member functions">
285 <method name="operator()" cv="const">
286 <type>result_type</type>
287 <parameter name="expr">
288 <paramtype>typename impl::expr_param</paramtype>
289 </parameter>
290 <parameter name="state">
291 <paramtype>typename impl::state_param</paramtype>
292 </parameter>
293 <parameter name="data">
294 <paramtype>typename impl::data_param</paramtype>
295 </parameter>
296 <description>
297 <para>
298 <computeroutput>
299 <classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()
300 </computeroutput>
301 behaves as follows:
302 </para>
303 <para>
304 <itemizedlist>
305 <listitem>
306 <para>
307 If <computeroutput>T</computeroutput> is of the form
308 <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then:
309 </para>
310 <itemizedlist>
311 <listitem>
312 <para>
313 If <computeroutput>
314 <classname>proto::is_aggregate</classname>&lt;result_type&gt;::value
315 </computeroutput> is <computeroutput>true</computeroutput>, then construct
316 and return an object <computeroutput>that</computeroutput> as follows:
317 <programlisting>result_type that = {
318 <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
319
320 <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
321 };</programlisting>
322 </para>
323 </listitem>
324 <listitem>
325 <para>
326 Otherwise, construct
327 and return an object <computeroutput>that</computeroutput> as follows:
328 <programlisting>result_type that(
329 <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
330
331 <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
332 );</programlisting>
333 </para>
334 </listitem>
335 </itemizedlist>
336 </listitem>
337 <listitem>
338 <para>
339 If <computeroutput>T</computeroutput> is of the form
340 <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
341 then let <computeroutput>T&apos;</computeroutput> be <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
342 where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
343 as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>. Then, return:
344 <programlisting>proto::make&lt;T&apos;&gt;()(expr, state, data)</programlisting>
345 </para>
346 </listitem>
347 <listitem>
348 <para>
349 Otherwise, construct and return an object <computeroutput>that</computeroutput>
350 as follows: <programlisting>result_type that = result_type();</programlisting>
351 </para>
352 </listitem>
353 </itemizedlist>
354 </para>
355 </description>
356 </method>
357 </method-group>
358 </struct>
359 </struct>
360 </namespace>
361 </namespace>
362 </header>