142 lines
6.5 KiB
XML
142 lines
6.5 KiB
XML
<?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>
|