/////////////////////////////////////////////////////////////////////////////// /// \file fold_tree.hpp /// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms. // // Copyright 2008 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) #ifndef BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007 #define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007 #include #include #include #include #include #include #include namespace boost { namespace proto { namespace transform { namespace detail { template struct has_tag : proto::callable { template struct result : mpl::false_ {}; template struct result : mpl::true_ {}; }; template struct fold_tree_ : if_, fold<_, _state, fold_tree_ >, Fun> {}; template struct reverse_fold_tree_ : if_, reverse_fold<_, _state, reverse_fold_tree_ >, Fun> {}; } /// \brief A PrimitiveTransform that recursively applies the /// fold\<\> transform to sub-trees that all share a common /// tag type. /// /// fold_tree\<\> is useful for flattening trees into lists; /// for example, you might use fold_tree\<\> to flatten an /// expression tree like a | b | c into a Fusion list like /// cons(c, cons(b, cons(a))). /// /// fold_tree\<\> is easily understood in terms of a /// recurse_if_\<\> helper, defined as follows: /// /// \code /// template /// struct recurse_if_ /// : if_< /// // If the current node has type type "Tag" ... /// is_same, Tag>() /// // ... recurse, otherwise ... /// , fold<_, _state, recurse_if_ > /// // ... apply the Fun transform. /// , Fun /// > /// {}; /// \endcode /// /// With recurse_if_\<\> as defined above, /// fold_tree\()(expr, state, visitor) is /// equivalent to /// fold >()(expr, state, visitor). /// It has the effect of folding a tree front-to-back, recursing into /// child nodes that share a tag type with the parent node. template struct fold_tree : proto::callable { template struct result; template struct result { /// \brief recurse_if_\, as described below. typedef detail::fold_tree_ recurse_if_; typedef fold impl; typedef typename impl::template result::type type; }; /// Let \c R be recurse_if_\ as described below. /// This function returns fold\()(expr, state, visitor). /// /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { typedef detail::fold_tree_ recurse_if_; return fold()(expr, state, visitor); } }; /// \brief A PrimitiveTransform that recursively applies the /// reverse_fold\<\> transform to sub-trees that all share /// a common tag type. /// /// reverse_fold_tree\<\> is useful for flattening trees into /// lists; for example, you might use reverse_fold_tree\<\> to /// flatten an expression tree like a | b | c into a Fusion list /// like cons(a, cons(b, cons(c))). /// /// reverse_fold_tree\<\> is easily understood in terms of a /// recurse_if_\<\> helper, defined as follows: /// /// \code /// template /// struct recurse_if_ /// : if_< /// // If the current node has type type "Tag" ... /// is_same, Tag>() /// // ... recurse, otherwise ... /// , reverse_fold<_, _state, recurse_if_ > /// // ... apply the Fun transform. /// , Fun /// > /// {}; /// \endcode /// /// With recurse_if_\<\> as defined above, /// reverse_fold_tree\()(expr, state, visitor) is /// equivalent to /// reverse_fold >()(expr, state, visitor). /// It has the effect of folding a tree back-to-front, recursing into /// child nodes that share a tag type with the parent node. template struct reverse_fold_tree : proto::callable { template struct result; template struct result { /// \brief recurse_if_\, as described below. typedef detail::reverse_fold_tree_ recurse_if_; typedef reverse_fold impl; typedef typename impl::template result::type type; }; /// Let \c R be recurse_if_\ as described below. /// This function returns reverse_fold\()(expr, state, visitor). /// /// \param expr The current expression /// \param state The current state /// \param visitor An arbitrary visitor template typename result::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { typedef detail::reverse_fold_tree_ recurse_if_; return reverse_fold()(expr, state, visitor); } }; } /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #endif