/////////////////////////////////////////////////////////////////////////////// /// \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 namespace boost { namespace proto { namespace detail { template struct has_tag { template struct impl { typedef mpl::false_ result_type; }; template struct impl { typedef mpl::true_ result_type; }; template struct impl { typedef mpl::true_ result_type; }; }; 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\()(e, s, d) is /// equivalent to /// fold >()(e, s, d). /// 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 : transform > { template struct impl : fold< Sequence , State0 , detail::fold_tree_ >::template impl {}; template struct impl : fold< Sequence , State0 , detail::fold_tree_ >::template impl {}; }; /// \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\()(e, s, d) is /// equivalent to /// reverse_fold >()(e, s, d). /// 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 : transform > { template struct impl : reverse_fold< Sequence , State0 , detail::reverse_fold_tree_ >::template impl {}; template struct impl : reverse_fold< Sequence , State0 , detail::reverse_fold_tree_ >::template impl {}; }; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #endif