1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2012 Eric Niebler
Distributed under the Boost
Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<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>
|