]>
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/fold_tree.hpp"> | |
10 | <para> | |
11 | Contains definition of the | |
12 | <computeroutput> | |
13 | <classname alt="boost::proto::fold_tree">proto::fold_tree<></classname> | |
14 | </computeroutput> and | |
15 | <computeroutput> | |
16 | <classname alt="boost::proto::reverse_fold_tree">proto::reverse_fold_tree<></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>< fold_tree<Sequence, State0, Fun> ></inherit> | |
29 | <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the | |
30 | <computeroutput><classname>proto::fold</classname><></computeroutput> transform to sub-trees | |
31 | that all share a common tag type.</purpose> | |
32 | <description> | |
33 | <para> | |
34 | <computeroutput>proto::fold_tree<></computeroutput> is useful for flattening trees into lists; | |
35 | for example, you might use <computeroutput>proto::fold_tree<></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<></computeroutput> is easily understood in terms of a | |
41 | <computeroutput>recurse_if_<></computeroutput> helper, defined as follows: | |
42 | <programlisting> template<typename Tag, typename Fun> | |
43 | struct recurse_if_ : | |
44 | <classname>proto::if_</classname>< | |
45 | // If the current node has type type "Tag" ... | |
46 | boost::is_same<<classname>proto::tag_of</classname><<classname>proto::_</classname>>, Tag>(), | |
47 | // ... recurse, otherwise ... | |
48 | <classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_<Tag, Fun> >, | |
49 | // ... apply the Fun transform. | |
50 | Fun | |
51 | > | |
52 | {};</programlisting> | |
53 | </para> | |
54 | <para> | |
55 | With <computeroutput>recurse_if_<></computeroutput> as defined above, | |
56 | <computeroutput>proto::fold_tree<Sequence, State0, Fun>()(expr, state, data)</computeroutput> | |
57 | is equivalent to: | |
58 | <programlisting><classname>proto::fold</classname>< | |
59 | Sequence, | |
60 | State0, | |
61 | recurse_if_<typename Expr::proto_tag, Fun> | |
62 | >()(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><Sequence, State0, recurse_if_<typename Expr::proto_tag, Fun> > | |
76 | ::template impl<Expr, State, Data></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>< reverse_fold_tree<Sequence, State0, Fun> ></inherit> | |
88 | <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the | |
89 | <computeroutput><classname>proto::reverse_fold<></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<></computeroutput> is useful for flattening trees | |
94 | into lists; for example, you might use <computeroutput>proto::reverse_fold_tree<></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<></computeroutput> is easily understood in terms of | |
100 | a <computeroutput>recurse_if_<></computeroutput> helper, defined as follows: | |
101 | <programlisting> template<typename Tag, typename Fun> | |
102 | struct recurse_if_ : | |
103 | <classname>proto::if_</classname>< | |
104 | // If the current node has type type "Tag" ... | |
105 | boost::is_same<<classname>proto::tag_of</classname><<classname>proto::_</classname>>, Tag>(), | |
106 | // ... recurse, otherwise ... | |
107 | <classname>proto::reverse_fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_<Tag, Fun> >, | |
108 | // ... apply the Fun transform. | |
109 | Fun | |
110 | > | |
111 | {};</programlisting> | |
112 | </para> | |
113 | <para> | |
114 | With <computeroutput>recurse_if_<></computeroutput> as defined above, | |
115 | <computeroutput>proto::reverse_fold_tree<Sequence, State0, Fun>()(expr, state, data)</computeroutput> | |
116 | is equivalent to: | |
117 | <programlisting><classname>proto::reverse_fold</classname>< | |
118 | Sequence, | |
119 | State0, | |
120 | recurse_if_<typename Expr::proto_tag, Fun> | |
121 | >()(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><Sequence, State0, recurse_if_<typename Expr::proto_tag, Fun> > | |
135 | ::template impl<Expr, State, Data></type> | |
136 | </inherit> | |
137 | </struct> | |
138 | </struct> | |
139 | </namespace> | |
140 | </namespace> | |
141 | </header> |