| <?xml version="1.0" encoding="utf-8"?> |
| <header name="boost/proto/transform/fold_tree.hpp"> |
| <para> |
| Contains definition of the |
| <computeroutput> |
| <classname alt="boost::proto::fold_tree">proto::fold_tree<></classname> |
| </computeroutput> and |
| <computeroutput> |
| <classname alt="boost::proto::reverse_fold_tree">proto::reverse_fold_tree<></classname> |
| </computeroutput> |
| transforms. |
| </para> |
| <namespace name="boost"> |
| <namespace name="proto"> |
| <struct name="fold_tree"> |
| <template> |
| <template-type-parameter name="Sequence"/> |
| <template-type-parameter name="State0"/> |
| <template-type-parameter name="Fun"/> |
| </template> |
| <inherit><classname>proto::transform</classname>< fold_tree<Sequence, State0, Fun> ></inherit> |
| <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the |
| <computeroutput><classname>proto::fold</classname><></computeroutput> transform to sub-trees |
| that all share a common tag type.</purpose> |
| <description> |
| <para> |
| <computeroutput>proto::fold_tree<></computeroutput> is useful for flattening trees into lists; |
| for example, you might use <computeroutput>proto::fold_tree<></computeroutput> to flatten an |
| expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like |
| <computeroutput>cons(c, cons(b, cons(a)))</computeroutput>. |
| </para> |
| <para> |
| <computeroutput>proto::fold_tree<></computeroutput> is easily understood in terms of a |
| <computeroutput>recurse_if_<></computeroutput> helper, defined as follows: |
| <programlisting> template<typename Tag, typename Fun> |
| struct recurse_if_ : |
| <classname>proto::if_</classname>< |
| // If the current node has type type "Tag" ... |
| boost::is_same<<classname>proto::tag_of</classname><<classname>proto::_</classname>>, Tag>(), |
| // ... recurse, otherwise ... |
| <classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_<Tag, Fun> >, |
| // ... apply the Fun transform. |
| Fun |
| > |
| {};</programlisting> |
| </para> |
| <para> |
| With <computeroutput>recurse_if_<></computeroutput> as defined above, |
| <computeroutput>proto::fold_tree<Sequence, State0, Fun>()(expr, state, data)</computeroutput> |
| is equivalent to: |
| <programlisting><classname>proto::fold</classname>< |
| Sequence, |
| State0, |
| recurse_if_<typename Expr::proto_tag, Fun> |
| >()(expr, state, data).</programlisting> |
| It has the effect of folding a tree front-to-back, recursing into child nodes that share a |
| tag type with the parent node. |
| </para> |
| </description> |
| <struct name="impl"> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <inherit> |
| <type> |
| <classname>proto::fold</classname><Sequence, State0, recurse_if_<typename Expr::proto_tag, Fun> > |
| ::template impl<Expr, State, Data></type> |
| </inherit> |
| </struct> |
| </struct> |
| |
| <struct name="reverse_fold_tree"> |
| <template> |
| <template-type-parameter name="Sequence"/> |
| <template-type-parameter name="State0"/> |
| <template-type-parameter name="Fun"/> |
| </template> |
| <inherit><classname>proto::transform</classname>< reverse_fold_tree<Sequence, State0, Fun> ></inherit> |
| <purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the |
| <computeroutput><classname>proto::reverse_fold<></classname></computeroutput> transform to |
| sub-trees that all share a common tag type.</purpose> |
| <description> |
| <para> |
| <computeroutput>proto::reverse_fold_tree<></computeroutput> is useful for flattening trees |
| into lists; for example, you might use <computeroutput>proto::reverse_fold_tree<></computeroutput> |
| to flatten an expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like |
| <computeroutput>cons(a, cons(b, cons(c)))</computeroutput>. |
| </para> |
| <para> |
| <computeroutput>proto::reverse_fold_tree<></computeroutput> is easily understood in terms of |
| a <computeroutput>recurse_if_<></computeroutput> helper, defined as follows: |
| <programlisting> template<typename Tag, typename Fun> |
| struct recurse_if_ : |
| <classname>proto::if_</classname>< |
| // If the current node has type type "Tag" ... |
| boost::is_same<<classname>proto::tag_of</classname><<classname>proto::_</classname>>, Tag>(), |
| // ... recurse, otherwise ... |
| <classname>proto::reverse_fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_<Tag, Fun> >, |
| // ... apply the Fun transform. |
| Fun |
| > |
| {};</programlisting> |
| </para> |
| <para> |
| With <computeroutput>recurse_if_<></computeroutput> as defined above, |
| <computeroutput>proto::reverse_fold_tree<Sequence, State0, Fun>()(expr, state, data)</computeroutput> |
| is equivalent to: |
| <programlisting><classname>proto::reverse_fold</classname>< |
| Sequence, |
| State0, |
| recurse_if_<typename Expr::proto_tag, Fun> |
| >()(expr, state, data).</programlisting> |
| It has the effect of folding a tree back-to-front, recursing into child nodes that share a |
| tag type with the parent node. |
| </para> |
| </description> |
| <struct name="impl"> |
| <template> |
| <template-type-parameter name="Expr"/> |
| <template-type-parameter name="State"/> |
| <template-type-parameter name="Data"/> |
| </template> |
| <inherit> |
| <type> |
| <classname>proto::reverse_fold</classname><Sequence, State0, recurse_if_<typename Expr::proto_tag, Fun> > |
| ::template impl<Expr, State, Data></type> |
| </inherit> |
| </struct> |
| </struct> |
| </namespace> |
| </namespace> |
| </header> |