Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file fold_tree.hpp Chris@16: /// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms. Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007 Chris@16: #define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace proto Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct has_tag Chris@16: { Chris@16: template Chris@16: struct impl Chris@16: { Chris@16: typedef mpl::false_ result_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: { Chris@16: typedef mpl::true_ result_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: { Chris@16: typedef mpl::true_ result_type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct fold_tree_ Chris@16: : if_, fold<_, _state, fold_tree_ >, Fun> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct reverse_fold_tree_ Chris@16: : if_, reverse_fold<_, _state, reverse_fold_tree_ >, Fun> Chris@16: {}; Chris@16: } Chris@16: Chris@16: /// \brief A PrimitiveTransform that recursively applies the Chris@16: /// fold\<\> transform to sub-trees that all share a common Chris@16: /// tag type. Chris@16: /// Chris@16: /// fold_tree\<\> is useful for flattening trees into lists; Chris@16: /// for example, you might use fold_tree\<\> to flatten an Chris@16: /// expression tree like a | b | c into a Fusion list like Chris@16: /// cons(c, cons(b, cons(a))). Chris@16: /// Chris@16: /// fold_tree\<\> is easily understood in terms of a Chris@16: /// recurse_if_\<\> helper, defined as follows: Chris@16: /// Chris@16: /// \code Chris@16: /// template Chris@16: /// struct recurse_if_ Chris@16: /// : if_< Chris@16: /// // If the current node has type "Tag" ... Chris@16: /// is_same, Tag>() Chris@16: /// // ... recurse, otherwise ... Chris@16: /// , fold<_, _state, recurse_if_ > Chris@16: /// // ... apply the Fun transform. Chris@16: /// , Fun Chris@16: /// > Chris@16: /// {}; Chris@16: /// \endcode Chris@16: /// Chris@16: /// With recurse_if_\<\> as defined above, Chris@16: /// fold_tree\()(e, s, d) is Chris@16: /// equivalent to Chris@16: /// fold >()(e, s, d). Chris@16: /// It has the effect of folding a tree front-to-back, recursing into Chris@16: /// child nodes that share a tag type with the parent node. Chris@16: template Chris@16: struct fold_tree Chris@16: : transform > Chris@16: { Chris@16: template Chris@16: struct impl Chris@16: : fold< Chris@16: Sequence Chris@16: , State0 Chris@16: , detail::fold_tree_ Chris@16: >::template impl Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: : fold< Chris@16: Sequence Chris@16: , State0 Chris@16: , detail::fold_tree_ Chris@16: >::template impl Chris@16: {}; Chris@16: }; Chris@16: Chris@16: /// \brief A PrimitiveTransform that recursively applies the Chris@16: /// reverse_fold\<\> transform to sub-trees that all share Chris@16: /// a common tag type. Chris@16: /// Chris@16: /// reverse_fold_tree\<\> is useful for flattening trees into Chris@16: /// lists; for example, you might use reverse_fold_tree\<\> to Chris@16: /// flatten an expression tree like a | b | c into a Fusion list Chris@16: /// like cons(a, cons(b, cons(c))). Chris@16: /// Chris@16: /// reverse_fold_tree\<\> is easily understood in terms of a Chris@16: /// recurse_if_\<\> helper, defined as follows: Chris@16: /// Chris@16: /// \code Chris@16: /// template Chris@16: /// struct recurse_if_ Chris@16: /// : if_< Chris@16: /// // If the current node has type "Tag" ... Chris@16: /// is_same, Tag>() Chris@16: /// // ... recurse, otherwise ... Chris@16: /// , reverse_fold<_, _state, recurse_if_ > Chris@16: /// // ... apply the Fun transform. Chris@16: /// , Fun Chris@16: /// > Chris@16: /// {}; Chris@16: /// \endcode Chris@16: /// Chris@16: /// With recurse_if_\<\> as defined above, Chris@16: /// reverse_fold_tree\()(e, s, d) is Chris@16: /// equivalent to Chris@16: /// reverse_fold >()(e, s, d). Chris@16: /// It has the effect of folding a tree back-to-front, recursing into Chris@16: /// child nodes that share a tag type with the parent node. Chris@16: template Chris@16: struct reverse_fold_tree Chris@16: : transform > Chris@16: { Chris@16: template Chris@16: struct impl Chris@16: : reverse_fold< Chris@16: Sequence Chris@16: , State0 Chris@16: , detail::reverse_fold_tree_ Chris@16: >::template impl Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: : reverse_fold< Chris@16: Sequence Chris@16: , State0 Chris@16: , detail::reverse_fold_tree_ Chris@16: >::template impl Chris@16: {}; Chris@16: }; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: template Chris@16: struct is_callable > Chris@16: : mpl::true_ Chris@16: {}; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: template Chris@16: struct is_callable > Chris@16: : mpl::true_ Chris@16: {}; Chris@16: Chris@16: }} Chris@16: Chris@16: #endif