1 <?xml version=
"1.0" encoding=
"utf-8"?>
3 Copyright 2012 Eric Niebler
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)
9 <header name=
"boost/proto/transform/fold_tree.hpp">
11 Contains definition of the
13 <classname alt=
"boost::proto::fold_tree">proto::fold_tree
<></classname>
16 <classname alt=
"boost::proto::reverse_fold_tree">proto::reverse_fold_tree
<></classname>
20 <namespace name=
"boost">
21 <namespace name=
"proto">
22 <struct name=
"fold_tree">
24 <template-type-parameter name=
"Sequence"/>
25 <template-type-parameter name=
"State0"/>
26 <template-type-parameter name=
"Fun"/>
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>
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>.
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
>
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.
55 With
<computeroutput>recurse_if_
<></computeroutput> as defined above,
56 <computeroutput>proto::fold_tree
<Sequence, State0, Fun
>()(expr, state, data)
</computeroutput>
58 <programlisting><classname>proto::fold
</classname><
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.
69 <template-type-parameter name=
"Expr"/>
70 <template-type-parameter name=
"State"/>
71 <template-type-parameter name=
"Data"/>
75 <classname>proto::fold
</classname><Sequence, State0, recurse_if_
<typename Expr::proto_tag, Fun
> >
76 ::template impl
<Expr, State, Data
></type>
81 <struct name=
"reverse_fold_tree">
83 <template-type-parameter name=
"Sequence"/>
84 <template-type-parameter name=
"State0"/>
85 <template-type-parameter name=
"Fun"/>
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>
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>.
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
>
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.
114 With
<computeroutput>recurse_if_
<></computeroutput> as defined above,
115 <computeroutput>proto::reverse_fold_tree
<Sequence, State0, Fun
>()(expr, state, data)
</computeroutput>
117 <programlisting><classname>proto::reverse_fold
</classname><
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.
128 <template-type-parameter name=
"Expr"/>
129 <template-type-parameter name=
"State"/>
130 <template-type-parameter name=
"Data"/>
134 <classname>proto::reverse_fold
</classname><Sequence, State0, recurse_if_
<typename Expr::proto_tag, Fun
> >
135 ::template impl
<Expr, State, Data
></type>