• 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/transform/fold_tree.hpp">
10  <para>
11    Contains definition of the
12    <computeroutput>
13      <classname alt="boost::proto::fold_tree">proto::fold_tree&lt;&gt;</classname>
14    </computeroutput> and
15    <computeroutput>
16      <classname alt="boost::proto::reverse_fold_tree">proto::reverse_fold_tree&lt;&gt;</classname>
17    </computeroutput>
18    transforms.
19  </para>
20  <namespace name="boost">
21    <namespace name="proto">
22      <struct name="fold_tree">
23        <template>
24          <template-type-parameter name="Sequence"/>
25          <template-type-parameter name="State0"/>
26          <template-type-parameter name="Fun"/>
27        </template>
28        <inherit><classname>proto::transform</classname>&lt; fold_tree&lt;Sequence, State0, Fun&gt; &gt;</inherit>
29        <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the
30          <computeroutput><classname>proto::fold</classname>&lt;&gt;</computeroutput> transform to sub-trees
31          that all share a common tag type.</purpose>
32        <description>
33          <para>
34            <computeroutput>proto::fold_tree&lt;&gt;</computeroutput> is useful for flattening trees into lists;
35            for example, you might use <computeroutput>proto::fold_tree&lt;&gt;</computeroutput> to flatten an
36            expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like
37            <computeroutput>cons(c, cons(b, cons(a)))</computeroutput>.
38          </para>
39          <para>
40            <computeroutput>proto::fold_tree&lt;&gt;</computeroutput> is easily understood in terms of a
41            <computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:
42            <programlisting> template&lt;typename Tag, typename Fun&gt;
43struct recurse_if_ :
44  <classname>proto::if_</classname>&lt;
45    // If the current node has type type "Tag" ...
46    boost::is_same&lt;<classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;, Tag&gt;(),
47    // ... recurse, otherwise ...
48    <classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_&lt;Tag, Fun&gt; &gt;,
49    // ... apply the Fun transform.
50    Fun
51  &gt;
52{};</programlisting>
53          </para>
54          <para>
55            With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above,
56            <computeroutput>proto::fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput>
57            is equivalent to:
58            <programlisting><classname>proto::fold</classname>&lt;
59  Sequence,
60  State0,
61  recurse_if_&lt;typename Expr::proto_tag, Fun&gt;
62&gt;()(expr, state, data).</programlisting>
63            It has the effect of folding a tree front-to-back, recursing into child nodes that share a
64            tag type with the parent node.
65          </para>
66        </description>
67        <struct name="impl">
68          <template>
69            <template-type-parameter name="Expr"/>
70            <template-type-parameter name="State"/>
71            <template-type-parameter name="Data"/>
72          </template>
73          <inherit>
74            <type>
75    <classname>proto::fold</classname>&lt;Sequence, State0, recurse_if_&lt;typename Expr::proto_tag, Fun&gt; &gt;
76      ::template impl&lt;Expr, State, Data&gt;</type>
77          </inherit>
78        </struct>
79      </struct>
80
81      <struct name="reverse_fold_tree">
82        <template>
83          <template-type-parameter name="Sequence"/>
84          <template-type-parameter name="State0"/>
85          <template-type-parameter name="Fun"/>
86        </template>
87        <inherit><classname>proto::transform</classname>&lt; reverse_fold_tree&lt;Sequence, State0, Fun&gt; &gt;</inherit>
88        <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the
89          <computeroutput><classname>proto::reverse_fold&lt;&gt;</classname></computeroutput> transform to
90          sub-trees that all share a common tag type.</purpose>
91        <description>
92          <para>
93            <computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput> is useful for flattening trees
94            into lists; for example, you might use <computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput>
95            to flatten an expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like
96            <computeroutput>cons(a, cons(b, cons(c)))</computeroutput>.
97          </para>
98          <para>
99            <computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput> is easily understood in terms of
100            a <computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:
101            <programlisting> template&lt;typename Tag, typename Fun&gt;
102struct recurse_if_ :
103  <classname>proto::if_</classname>&lt;
104    // If the current node has type type "Tag" ...
105    boost::is_same&lt;<classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;, Tag&gt;(),
106    // ... recurse, otherwise ...
107    <classname>proto::reverse_fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_&lt;Tag, Fun&gt; &gt;,
108    // ... apply the Fun transform.
109    Fun
110  &gt;
111{};</programlisting>
112          </para>
113          <para>
114            With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above,
115            <computeroutput>proto::reverse_fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput>
116            is equivalent to:
117            <programlisting><classname>proto::reverse_fold</classname>&lt;
118  Sequence,
119  State0,
120  recurse_if_&lt;typename Expr::proto_tag, Fun&gt;
121&gt;()(expr, state, data).</programlisting>
122            It has the effect of folding a tree back-to-front, recursing into child nodes that share a
123            tag type with the parent node.
124          </para>
125        </description>
126        <struct name="impl">
127          <template>
128            <template-type-parameter name="Expr"/>
129            <template-type-parameter name="State"/>
130            <template-type-parameter name="Data"/>
131          </template>
132          <inherit>
133            <type>
134    <classname>proto::reverse_fold</classname>&lt;Sequence, State0, recurse_if_&lt;typename Expr::proto_tag, Fun&gt; &gt;
135      ::template impl&lt;Expr, State, Data&gt;</type>
136          </inherit>
137        </struct>
138      </struct>
139    </namespace>
140  </namespace>
141</header>
142