• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/make_expr.hpp">
10  <para>
11    Definition of the <computeroutput><functionname alt="boost::proto::make_expr">proto::make_expr()</functionname>
12    </computeroutput> and <computeroutput><functionname alt="boost::proto::unpack_expr">proto::unpack_expr()</functionname>
13    </computeroutput> utilities for building Proto expression nodes from child nodes or from a Fusion sequence of child
14    nodes, respectively.
15  </para>
16  <namespace name="boost">
17    <namespace name="proto">
18      <namespace name="functional">
19        <!-- proto::functional::make_expr -->
20        <struct name="make_expr">
21          <template>
22            <template-type-parameter name="Tag"/>
23            <template-type-parameter name="Domain">
24              <default><classname>proto::deduce_domain</classname></default>
25            </template-type-parameter>
26          </template>
27          <purpose>A <conceptname>PolymorphicFunctionObject</conceptname> equivalent to the <computeroutput>
28            <functionname alt="proto::make_expr">proto::make_expr()</functionname></computeroutput> function.</purpose>
29          <description>
30            <para>
31              In all cases, <computeroutput>proto::functional::make_expr&lt;Tag, Domain&gt;()(a...)</computeroutput>
32              is equivalent to <computeroutput><functionname>proto::make_expr</functionname>&lt;Tag, Domain&gt;(a...)</computeroutput>.
33            </para>
34            <para>
35              <computeroutput>proto::functional::make_expr&lt;Tag&gt;()(a...)</computeroutput> is equivalent to
36              <computeroutput><functionname>proto::make_expr</functionname>&lt;Tag&gt;(a...)</computeroutput>.
37            </para>
38          </description>
39          <inherit>
40            <type><classname>proto::callable</classname></type>
41          </inherit>
42          <struct-specialization name="result">
43            <template>
44              <template-type-parameter name="This"/>
45              <template-type-parameter name="A" pack="1"/>
46            </template>
47            <specialization>
48              <template-arg>This(A...)</template-arg>
49            </specialization>
50            <inherit>
51              <type>
52    <classname>proto::result_of::make_expr</classname>&lt; Tag, Domain, A... &gt;</type>
53            </inherit>
54          </struct-specialization>
55          <method-group name="public member functions">
56            <method name="operator()" cv="const">
57              <type>typename <classname>proto::result_of::make_expr</classname>&lt; Tag, Domain, A const... &gt;::type const</type>
58              <template>
59                <template-type-parameter name="A" pack="1"/>
60              </template>
61              <parameter name="a" pack="1">
62                <paramtype>A const &amp;</paramtype>
63              </parameter>
64              <description>
65                <para>
66                  Construct an expression node with tag type <computeroutput>Tag</computeroutput> and in the
67                  domain <computeroutput>Domain</computeroutput>.
68                </para>
69                <para>
70                </para>
71              </description>
72              <returns>
73                <para>
74                  <computeroutput><functionname>proto::make_expr</functionname>&lt;Tag, Domain&gt;(a...)</computeroutput>
75                </para>
76              </returns>
77            </method>
78          </method-group>
79        </struct>
80
81        <!-- proto::functional::unpack_expr -->
82        <struct name="unpack_expr">
83          <template>
84            <template-type-parameter name="Tag"/>
85            <template-type-parameter name="Domain">
86              <default><classname>proto::deduce_domain</classname></default>
87            </template-type-parameter>
88          </template>
89          <purpose>A <conceptname>PolymorphicFunctionObject</conceptname> equivalent to the
90            <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname></computeroutput> function.
91          </purpose>
92          <description>
93            <para>
94              In all cases, <computeroutput>proto::functional::unpack_expr&lt;Tag, Domain&gt;()(seq)</computeroutput> is
95              equivalent to <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname>&lt;Tag,
96              Domain&gt;(seq)</computeroutput>.
97            </para>
98            <para>
99              <computeroutput>proto::functional::unpack_expr&lt;Tag&gt;()(seq)</computeroutput> is equivalent to
100              <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname>&lt;Tag&gt;(seq)</computeroutput>.
101            </para>
102          </description>
103          <inherit>
104            <type><classname>proto::callable</classname></type>
105          </inherit>
106          <struct-specialization name="result">
107            <template>
108              <template-type-parameter name="This"/>
109              <template-type-parameter name="Sequence"/>
110            </template>
111            <specialization>
112              <template-arg>This(Sequence)</template-arg>
113            </specialization>
114            <inherit>
115              <type>
116    <classname>proto::result_of::unpack_expr</classname>&lt;
117      Tag,
118      Domain,
119      typename boost::remove_reference&lt; Sequence &gt;::type
120    &gt;</type>
121            </inherit>
122          </struct-specialization>
123          <method-group name="public member functions">
124            <method name="operator()" cv="const">
125              <type>typename <classname>proto::result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence const &gt;::type const</type>
126              <template>
127                <template-type-parameter name="Sequence"/>
128              </template>
129              <parameter name="sequence">
130                <paramtype>Sequence const &amp;</paramtype>
131                <description>
132                  <para>A Fusion Forward Sequence </para>
133                </description>
134              </parameter>
135              <description>
136                <para>
137                  Construct an expression node with tag type <computeroutput>Tag</computeroutput> and in the
138                  domain <computeroutput>Domain</computeroutput>.
139                </para>
140              </description>
141              <returns>
142                <para>
143                  <computeroutput><functionname>proto::unpack_expr</functionname>&lt;Tag, Domain&gt;(sequence)</computeroutput>
144                </para>
145              </returns>
146            </method>
147          </method-group>
148        </struct>
149      </namespace>
150
151      <namespace name="result_of">
152        <!-- proto::result_of::make_expr -->
153        <struct name="make_expr">
154          <template>
155            <template-type-parameter name="Tag"/>
156            <template-type-parameter name="A" pack="1"/>
157          </template>
158          <purpose>Metafunction that computes the return type of the
159            <computeroutput><functionname alt="proto::make_expr">proto::make_expr()</functionname></computeroutput>
160            function, with a domain deduced from the domains of the children.</purpose>
161          <description>
162            <para>
163              Computes the return type of the
164              <computeroutput><functionname alt="proto::make_expr">proto::make_expr()</functionname></computeroutput> function.
165            </para>
166            <para>
167              In this specialization, the domain is deduced from the domains of the child types.
168              If <computeroutput><classname>proto::is_domain</classname>&lt;A<subscript>0</subscript>&gt;::value</computeroutput>
169              is <computeroutput>true</computeroutput>, then another specialization is selected.
170            </para>
171          </description>
172          <typedef name="D">
173            <purpose>For exposition only</purpose>
174            <type><replaceable>domain-deduced-from-child-types</replaceable></type>
175            <description>
176              <para>
177                In this specialization, Proto uses the domains of the child expressions to compute the
178                domain of the parent. See
179                <computeroutput><classname>proto::deduce_domain</classname></computeroutput> for a full
180                description of the procedure used.
181              </para>
182            </description>
183          </typedef>
184          <typedef name="type">
185            <type>typename <classname>proto::result_of::make_expr</classname>&lt;Tag, D, A...&gt;::type</type>
186          </typedef>
187        </struct>
188        <struct-specialization name="make_expr">
189          <template>
190            <template-type-parameter name="Tag"/>
191            <template-type-parameter name="Domain"/>
192            <template-type-parameter name="A" pack="1"/>
193          </template>
194          <specialization>
195            <template-arg>Tag</template-arg>
196            <template-arg>Domain</template-arg>
197            <template-arg pack="1">A</template-arg>
198          </specialization>
199          <purpose>Metafunction that computes the return type of the
200            <computeroutput><functionname alt="proto::make_expr">proto::make_expr()</functionname></computeroutput>
201            function, within the specified domain.</purpose>
202          <description>
203            <para>
204              Computes the return type of the
205              <computeroutput><functionname alt="proto::make_expr">proto::make_expr()</functionname></computeroutput>
206              function.
207            </para>
208          </description>
209          <typedef name="type">
210            <description>
211              <para>
212                Let <computeroutput><replaceable>WRAP&lt;X&gt;</replaceable></computeroutput> be defined such that:
213                <itemizedlist>
214                  <listitem>
215                    <para>
216                      If <computeroutput>X</computeroutput> is <computeroutput>Y &amp;</computeroutput>
217                      or (possibly cv-qualified) <computeroutput>boost::reference_wrapper&lt;Y&gt;</computeroutput>,
218                      then <computeroutput><replaceable>WRAP&lt;X&gt;</replaceable></computeroutput> is equivalent to
219                      <computeroutput><classname>proto::result_of::as_child</classname>&lt;Y, Domain&gt;</computeroutput>.
220                    </para>
221                  </listitem>
222                  <listitem>
223                    <para>
224                      Otherwise, <computeroutput><replaceable>WRAP&lt;X&gt;</replaceable></computeroutput> is equivalent to
225                      <computeroutput><classname>proto::result_of::as_expr</classname>&lt;X, Domain&gt;</computeroutput>.
226                    </para>
227                  </listitem>
228                </itemizedlist>
229              </para>
230              <para>
231                If <computeroutput><classname>proto::wants_basic_expr</classname>&lt;typename Domain::proto_generator&gt;::value</computeroutput>
232                is true, then let <computeroutput><replaceable>E</replaceable></computeroutput> be
233                <computeroutput><classname>proto::basic_expr</classname></computeroutput>; otherwise,
234                let <computeroutput><replaceable>E</replaceable></computeroutput> be
235                <computeroutput><classname>proto::expr</classname></computeroutput>.
236              </para>
237              <para>
238                If <computeroutput>Tag</computeroutput> is
239                <computeroutput><classname>proto::tag::terminal</classname></computeroutput>, then
240                <computeroutput>type</computeroutput> is a typedef for
241                <computeroutput>typename <replaceable>WRAP&lt;A<subscript>0</subscript>&gt;</replaceable>::type</computeroutput>.
242              </para>
243              <para>
244                Otherwise, <computeroutput>type</computeroutput> is a typedef for
245                <computeroutput>boost::result_of&lt;Domain(<replaceable>E</replaceable>&lt;
246                Tag, <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;
247                typename <replaceable>WRAP&lt;A&gt;</replaceable>::type...&gt; &gt;)&gt;::type</computeroutput>
248              </para>
249            </description>
250            <type><emphasis>see-below</emphasis></type>
251          </typedef>
252        </struct-specialization>
253        <!-- proto::result_of::unpack_expr -->
254        <struct name="unpack_expr">
255          <template>
256            <template-type-parameter name="Tag"/>
257            <template-type-parameter name="Sequence"/>
258            <template-type-parameter name="Void">
259              <default><type>void</type></default>
260            </template-type-parameter>
261          </template>
262          <purpose>Metafunction that computes the return type of the
263            <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname></computeroutput>
264            function, with a domain deduced from the domains of the children.
265          </purpose>
266          <description>
267            <para>
268              Compute the return type of the
269              <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname></computeroutput>
270              function.
271            </para>
272            <para>
273              <computeroutput>Sequence</computeroutput> is a Fusion Forward Sequence.
274            </para>
275            <para>
276              In this specialization, the domain is deduced from the domains of the child types.
277              If <computeroutput><classname>proto::is_domain</classname>&lt;Sequence&gt;::value</computeroutput>
278              is <computeroutput>true</computeroutput>, then another specialization is selected.
279            </para>
280          </description>
281          <typedef name="type">
282            <purpose>Where S is a Fusion RandomAccessSequence equivalent to Sequence, and N is the size of S.</purpose>
283            <type>
284    typename <classname>proto::result_of::make_expr</classname>&lt;
285      Tag,
286      typename fusion::result_of::value_at_c&lt;<replaceable>S</replaceable>, 0&gt;::type,
287      ...
288      typename fusion::result_of::value_at_c&lt;<replaceable>S</replaceable>, <replaceable>N</replaceable>-1&gt;::type
289    &gt;::type
290  </type>
291          </typedef>
292        </struct>
293        <struct-specialization name="unpack_expr">
294          <template>
295            <template-type-parameter name="Tag"/>
296            <template-type-parameter name="Domain"/>
297            <template-type-parameter name="Sequence"/>
298          </template>
299          <specialization>
300            <template-arg>Tag</template-arg>
301            <template-arg>Domain</template-arg>
302            <template-arg>Sequence</template-arg>
303          </specialization>
304          <purpose>Metafunction that computes the return type of the
305            <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname></computeroutput>
306            function, within the specified domain.
307          </purpose>
308          <description>
309            <para>
310              Computes the return type of the
311              <computeroutput><functionname alt="proto::unpack_expr">proto::unpack_expr()</functionname></computeroutput>
312              function.
313            </para>
314          </description>
315          <typedef name="type">
316            <purpose>Where S is a RandomAccessSequence equivalent to Sequence, and N is the size of S.</purpose>
317            <type>
318    typename <classname>proto::result_of::make_expr</classname>&lt;
319      Tag,
320      Domain,
321      typename fusion::result_of::value_at_c&lt;<replaceable>S</replaceable>, 0&gt;::type,
322      ...
323      typename fusion::result_of::value_at_c&lt;<replaceable>S</replaceable>, <replaceable>N</replaceable>-1&gt;::type
324    &gt;::type
325  </type>
326          </typedef>
327        </struct-specialization>
328      </namespace>
329
330      <!-- proto::make_expr() -->
331      <overloaded-function name="make_expr">
332        <signature>
333          <type>typename <classname>proto::result_of::make_expr</classname>&lt;Tag, A const...&gt;::type const</type>
334          <template>
335            <template-type-parameter name="Tag"/>
336            <template-type-parameter name="A" pack="1"/>
337          </template>
338          <parameter name="a" pack="1">
339            <paramtype>A const &amp;</paramtype>
340          </parameter>
341        </signature>
342        <signature>
343          <type>typename <classname>proto::result_of::make_expr</classname>&lt;Tag, Domain, A const...&gt;::type const</type>
344          <template>
345            <template-type-parameter name="Tag"/>
346            <template-type-parameter name="Domain"/>
347            <template-type-parameter name="A" pack="1"/>
348          </template>
349          <parameter name="a" pack="1">
350            <paramtype>A const &amp;</paramtype>
351          </parameter>
352        </signature>
353        <purpose>Construct an expression of the requested tag type with a domain and with the specified
354          arguments as children.</purpose>
355        <description>
356          <para>
357            This function template may be invoked either with or without specifying a
358            <computeroutput>Domain</computeroutput> template parameter. If no domain is specified, the domain
359            is deduced by examining domains of the given arguments. See
360            <computeroutput><classname>proto::deduce_domain</classname></computeroutput> for a full
361            description of the procedure used.
362          </para>
363          <para>
364            Let <computeroutput><replaceable>WRAP</replaceable>(x)</computeroutput> be defined such that:
365            <itemizedlist>
366              <listitem>
367                <para>
368                  If <computeroutput>x</computeroutput> is a <computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>,
369                  <computeroutput><replaceable>WRAP</replaceable>(x)</computeroutput> is equivalent to
370                  <computeroutput><functionname>proto::as_child</functionname>&lt;Domain&gt;(x.get())</computeroutput>.
371                </para>
372              </listitem>
373              <listitem>
374                <para>
375                  Otherwise, <computeroutput><replaceable>WRAP</replaceable>(x)</computeroutput> is equivalent to
376                  <computeroutput><functionname>proto::as_expr</functionname>&lt;Domain&gt;(x)</computeroutput>.
377                </para>
378              </listitem>
379            </itemizedlist>
380          </para>
381          <para>
382            If <computeroutput><classname>proto::wants_basic_expr</classname>&lt;typename Domain::proto_generator&gt;::value</computeroutput>
383            is true, then let <computeroutput><replaceable>E</replaceable></computeroutput> be
384            <computeroutput><classname>proto::basic_expr</classname></computeroutput>; otherwise,
385            let <computeroutput><replaceable>E</replaceable></computeroutput> be
386            <computeroutput><classname>proto::expr</classname></computeroutput>.
387          </para>
388          <para>
389            Let <computeroutput><replaceable>MAKE</replaceable>(Tag, b...)</computeroutput> be defined as
390            <computeroutput><replaceable>E</replaceable>&lt;Tag,
391            <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;decltype(b)...&gt; &gt;::make(b...)</computeroutput>.
392          </para>
393          <para>
394            If <computeroutput>Tag</computeroutput> is
395            <computeroutput><classname>proto::tag::terminal</classname></computeroutput>, then return
396            <computeroutput><replaceable>WRAP</replaceable>(a<subscript>0</subscript>)</computeroutput>.
397          </para>
398          <para>
399            Otherwise, return
400            <computeroutput>Domain()(<replaceable>MAKE</replaceable>(Tag, <replaceable>WRAP</replaceable>(a)...))</computeroutput>.
401          </para>
402        </description>
403      </overloaded-function>
404
405      <!-- proto::unpack_expr() -->
406      <overloaded-function name="unpack_expr">
407        <signature>
408          <type>typename <classname>proto::result_of::unpack_expr</classname>&lt;Tag, Sequence const&gt;::type const</type>
409          <template>
410            <template-type-parameter name="Tag"/>
411            <template-type-parameter name="Sequence"/>
412          </template>
413          <parameter name="sequence">
414            <paramtype>Sequence const &amp;</paramtype>
415            <description>
416              <para>A Fusion Forward Sequence.</para>
417            </description>
418          </parameter>
419        </signature>
420        <signature>
421          <type>typename <classname>proto::result_of::unpack_expr</classname>&lt;Tag, Domain, Sequence const&gt;::type const</type>
422          <template>
423            <template-type-parameter name="Tag"/>
424            <template-type-parameter name="Domain"/>
425            <template-type-parameter name="Sequence"/>
426          </template>
427          <parameter name="sequence">
428            <paramtype>Sequence const &amp;</paramtype>
429          </parameter>
430        </signature>
431        <purpose>Construct an expression of the requested tag type with a domain and with children
432          from the specified Fusion Forward Sequence.</purpose>
433        <description>
434          <para>
435            This function template may be invoked either with or without specifying a
436            <computeroutput>Domain</computeroutput> argument. If no domain is specified, the domain
437            is deduced by examining domains of each element of the sequence. See
438            <computeroutput><classname>proto::deduce_domain</classname></computeroutput> for a full
439            description of the procedure used.
440          </para>
441          <para>
442            Let <computeroutput>s</computeroutput> be a Fusion RandomAccessSequence equivalent to
443            <computeroutput>sequence</computeroutput>.
444            Let <computeroutput><replaceable>WRAP</replaceable>(N, s)</computeroutput> be defined such that:
445            <itemizedlist>
446              <listitem>
447                <para>
448                  If <computeroutput>fusion::result_of::value_at_c&lt;decltype(s),N&gt;::type</computeroutput> is a reference type
449                  or an instantiation of <computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>,
450                  <computeroutput><replaceable>WRAP</replaceable>(N, s)</computeroutput> is equivalent to
451                  <computeroutput><functionname>proto::as_child</functionname>&lt;Domain&gt;(fusion::at_c&lt;N&gt;(s))</computeroutput>.
452                </para>
453              </listitem>
454              <listitem>
455                <para>
456                  Otherwise, <computeroutput><replaceable>WRAP</replaceable>(N, s)</computeroutput> is equivalent to
457                  <computeroutput><functionname>proto::as_expr</functionname>&lt;Domain&gt;(fusion::at_c&lt;N&gt;(s))</computeroutput>.
458                </para>
459              </listitem>
460            </itemizedlist>
461          </para>
462          <para>
463            If <computeroutput><classname>proto::wants_basic_expr</classname>&lt;typename Domain::proto_generator&gt;::value</computeroutput>
464            is true, then let <computeroutput><replaceable>E</replaceable></computeroutput> be
465            <computeroutput><classname>proto::basic_expr</classname></computeroutput>; otherwise,
466            let <computeroutput><replaceable>E</replaceable></computeroutput> be
467            <computeroutput><classname>proto::expr</classname></computeroutput>.
468          </para>
469          <para>
470            Let <computeroutput><replaceable>MAKE</replaceable>(Tag, b...)</computeroutput> be defined as
471            <computeroutput><replaceable>E</replaceable>&lt;Tag,
472            <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;decltype(b)...&gt; &gt;::make(b...)</computeroutput>.
473          </para>
474          <para>
475            If <computeroutput>Tag</computeroutput> is
476            <computeroutput><classname>proto::tag::terminal</classname></computeroutput>, then return
477            <computeroutput><replaceable>WRAP</replaceable>(0, s)</computeroutput>.
478          </para>
479          <para>
480            Otherwise, return
481            <computeroutput>Domain()(<replaceable>MAKE</replaceable>(Tag, <replaceable>WRAP</replaceable>(0, s),...
482            <replaceable>WRAP</replaceable>(<replaceable>N</replaceable>-1, s)))</computeroutput>, where
483            <replaceable>N</replaceable> is the size of <computeroutput>Sequence</computeroutput>.
484          </para>
485        </description>
486      </overloaded-function>
487    </namespace>
488  </namespace>
489</header>
490