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> 43struct 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> 102struct 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> 142