$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66805 - in trunk/boost/proto: . functional functional/fusion functional/std transform
From: eric_at_[hidden]
Date: 2010-11-28 00:04:53
Author: eric_niebler
Date: 2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
New Revision: 66805
URL: http://svn.boost.org/trac/boost/changeset/66805
Log:
fix long-standing bug in proto::make, add more callable wrappers for std utility and fusion algos, reorg and clean-up
Added:
   trunk/boost/proto/functional/
   trunk/boost/proto/functional.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/
   trunk/boost/proto/functional/fusion.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/pop_back.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/pop_front.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/push_back.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/push_front.hpp   (contents, props changed)
   trunk/boost/proto/functional/fusion/reverse.hpp   (contents, props changed)
   trunk/boost/proto/functional/std/
   trunk/boost/proto/functional/std.hpp   (contents, props changed)
   trunk/boost/proto/functional/std/utility.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/proto/fusion.hpp              |   120 +++-------------------------------------
   trunk/boost/proto/make_expr.hpp           |    67 ----------------------                  
   trunk/boost/proto/matches.hpp             |     7 ++                                      
   trunk/boost/proto/proto.hpp               |     1                                         
   trunk/boost/proto/proto_fwd.hpp           |    12 +---                                    
   trunk/boost/proto/traits.hpp              |    44 +++++++++++---                          
   trunk/boost/proto/transform/default.hpp   |     2                                         
   trunk/boost/proto/transform/fold_tree.hpp |     1                                         
   trunk/boost/proto/transform/make.hpp      |    34 ++++++++---                             
   trunk/boost/proto/transform/when.hpp      |     7 ++                                      
   10 files changed, 87 insertions(+), 208 deletions(-)
Added: trunk/boost/proto/functional.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,15 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file functional.hpp
+/// Proto callables for various things
+//
+//  Copyright 2010 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_FUNCTIONAL_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_HPP_EAN_11_27_2010
+
+#include <boost/proto/functional/std.hpp>
+#include <boost/proto/functional/fusion.hpp>
+
+#endif
Added: trunk/boost/proto/functional/fusion.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,18 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fusion.hpp
+/// Proto callables for things found in the Fusion library
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_HPP_EAN_11_27_2010
+
+#include <boost/proto/functional/fusion/pop_back.hpp>
+#include <boost/proto/functional/fusion/pop_front.hpp>
+#include <boost/proto/functional/fusion/push_back.hpp>
+#include <boost/proto/functional/fusion/push_front.hpp>
+#include <boost/proto/functional/fusion/reverse.hpp>
+
+#endif
Added: trunk/boost/proto/functional/fusion/pop_back.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion/pop_back.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file pop_back.hpp
+/// Proto callables Fusion pop_back
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_POP_BACK_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_POP_BACK_HPP_EAN_11_27_2010
+
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/prior.hpp>
+#include <boost/fusion/include/pop_back.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::pop_back() algorithm on its argument.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::pop_back() algorithm on its argument.
+    struct pop_back
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Seq>
+        struct result<This(Seq)>
+          : result<This(Seq const &)>
+        {};
+
+        template<typename This, typename Seq>
+        struct result<This(Seq &)>
+          : fusion::result_of::pop_back<Seq>
+        {};
+
+        template<typename Seq>
+        typename fusion::result_of::pop_back<Seq>::type
+        operator ()(Seq &seq) const
+        {
+            // Work around a const-correctness issue in Fusion
+            typedef typename fusion::result_of::pop_back<Seq>::type result_type;
+            return result_type(fusion::begin(seq), fusion::prior(fusion::end(seq)));
+        }
+
+        template<typename Seq>
+        typename fusion::result_of::pop_back<Seq const>::type
+        operator ()(Seq const &seq) const
+        {
+            return fusion::pop_back(seq);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/proto/functional/fusion/pop_front.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion/pop_front.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file pop_front.hpp
+/// Proto callables Fusion pop_front
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_POP_FRONT_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_POP_FRONT_HPP_EAN_11_27_2010
+
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/next.hpp>
+#include <boost/fusion/include/pop_front.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::pop_front() algorithm on its argument.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::pop_front() algorithm on its argument. This is
+    /// useful for defining a CallableTransform like \c pop_front(_)
+    /// which removes the first child from a Proto expression node.
+    /// Such a transform might be used as the first argument to the
+    /// \c proto::fold\<\> transform; that is, fold all but
+    /// the first child.
+    struct pop_front
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Seq>
+        struct result<This(Seq)>
+          : result<This(Seq const &)>
+        {};
+
+        template<typename This, typename Seq>
+        struct result<This(Seq &)>
+          : fusion::result_of::pop_front<Seq>
+        {};
+
+        template<typename Seq>
+        typename fusion::result_of::pop_front<Seq>::type
+        operator ()(Seq &seq) const
+        {
+            // Work around a const-correctness issue in Fusion
+            typedef typename fusion::result_of::pop_front<Seq>::type result_type;
+            return result_type(fusion::next(fusion::begin(seq)), fusion::end(seq));
+        }
+
+        template<typename Seq>
+        typename fusion::result_of::pop_front<Seq const>::type
+        operator ()(Seq const &seq) const
+        {
+            return fusion::pop_front(seq);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/proto/functional/fusion/push_back.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion/push_back.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file push_back.hpp
+/// Proto callables Fusion push_back
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_PUSH_BACK_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_PUSH_BACK_HPP_EAN_11_27_2010
+
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/fusion/include/push_back.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::push_back() algorithm on its argument.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::push_back() algorithm on its argument.
+    struct push_back
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Seq, typename T>
+        struct result<This(Seq, T)>
+          : fusion::result_of::push_back<
+                typename boost::add_const<typename boost::remove_reference<Seq>::type>::type
+              , typename boost::remove_const<typename boost::remove_reference<T>::type>::type
+            >
+        {};
+
+        template<typename Seq, typename T>
+        typename fusion::result_of::push_back<Seq const, T>::type
+        operator ()(Seq const &seq, T const &t) const
+        {
+            return fusion::push_back(seq, t);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/proto/functional/fusion/push_front.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion/push_front.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file push_front.hpp
+/// Proto callables Fusion push_front
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_PUSH_FRONT_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_PUSH_FRONT_HPP_EAN_11_27_2010
+
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/fusion/include/push_front.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::push_front() algorithm on its argument.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::push_front() algorithm on its argument.
+    struct push_front
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Seq, typename T>
+        struct result<This(Seq, T)>
+          : fusion::result_of::push_front<
+                typename boost::add_const<typename boost::remove_reference<Seq>::type>::type
+              , typename boost::remove_const<typename boost::remove_reference<T>::type>::type
+            >
+        {};
+
+        template<typename Seq, typename T>
+        typename fusion::result_of::push_front<Seq const, T>::type
+        operator ()(Seq const &seq, T const &t) const
+        {
+            return fusion::push_front(seq, t);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/proto/functional/fusion/reverse.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/fusion/reverse.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file reverse.hpp
+/// Proto callables Fusion reverse
+//
+//  Copyright 2010 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_FUNCTIONAL_FUSION_REVERSE_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_FUSION_REVERSE_HPP_EAN_11_27_2010
+
+#include <boost/fusion/include/reverse.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::reverse() algorithm on its argument.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c fusion::reverse() algorithm on its argument. This is
+    /// useful for defining a CallableTransform like \c reverse(_)
+    /// which reverses the order of the children of a Proto
+    /// expression node.
+    struct reverse
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Seq>
+        struct result<This(Seq)>
+          : result<This(Seq const &)>
+        {};
+
+        template<typename This, typename Seq>
+        struct result<This(Seq &)>
+          : fusion::result_of::reverse<Seq>
+        {};
+
+        template<typename Seq>
+        typename fusion::result_of::reverse<Seq>::type
+        operator ()(Seq &seq) const
+        {
+            // Work around a const-correctness issue in Fusion
+            typedef typename fusion::result_of::reverse<Seq>::type result_type;
+            return result_type(seq);
+        }
+
+        template<typename Seq>
+        typename fusion::result_of::reverse<Seq const>::type
+        operator ()(Seq const &seq) const
+        {
+            return fusion::reverse(seq);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/proto/functional/std.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/std.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,14 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file std.hpp
+/// Proto callables for things found in the std library
+//
+//  Copyright 2010 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_FUNCTIONAL_STD_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_STD_HPP_EAN_11_27_2010
+
+#include <boost/proto/functional/std/utility.hpp>
+
+#endif
Added: trunk/boost/proto/functional/std/utility.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/functional/std/utility.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -0,0 +1,137 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file utility.hpp
+/// Proto callables for things found in the std \<utility\> header
+//
+//  Copyright 2010 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_FUNCTIONAL_STD_UTILITY_HPP_EAN_11_27_2010
+#define BOOST_PROTO_FUNCTIONAL_STD_UTILITY_HPP_EAN_11_27_2010
+
+#include <utility>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto { namespace functional
+{
+    /// \brief A PolymorphicFunctionObject type that invokes the
+    /// \c std::make_pair() algorithm on its arguments.
+    ///
+    /// A PolymorphicFunctionObject type that invokes the
+    /// \c std::make_pair() algorithm on its arguments.
+    struct make_pair
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename First, typename Second>
+        struct result<This(First, Second)>
+        {
+            typedef
+                std::pair<
+                    typename remove_const<typename remove_reference<First>::type>::type
+                  , typename remove_const<typename remove_reference<Second>::type>::type
+                >
+            type;
+        };
+
+        template<typename First, typename Second>
+        std::pair<First, Second> operator()(First const &first, Second const &second) const
+        {
+            return std::make_pair(first, second);
+        }
+    };
+
+    /// \brief A PolymorphicFunctionObject type that returns
+    /// the first element of a std::pair.
+    ///
+    /// A PolymorphicFunctionObject type that returns
+    /// the first element of a std::pair..
+    struct first
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Pair>
+        struct result<This(Pair)>
+        {
+            typedef typename Pair::first_type type;
+        };
+
+        template<typename This, typename Pair>
+        struct result<This(Pair &)>
+        {
+            typedef typename Pair::first_type &type;
+        };
+
+        template<typename This, typename Pair>
+        struct result<This(Pair const &)>
+        {
+            typedef typename Pair::first_type const &type;
+        };
+
+        template<typename Pair>
+        typename Pair::first_type &operator()(Pair &pair) const
+        {
+            return pair.first;
+        }
+
+        template<typename Pair>
+        typename Pair::first_type const &operator()(Pair const &pair) const
+        {
+            return pair.first;
+        }
+    };
+
+    /// \brief A PolymorphicFunctionObject type that returns
+    /// the second element of a std::pair.
+    ///
+    /// A PolymorphicFunctionObject type that returns
+    /// the second element of a std::pair..
+    struct second
+    {
+        BOOST_PROTO_CALLABLE()
+
+        template<typename Sig>
+        struct result;
+
+        template<typename This, typename Pair>
+        struct result<This(Pair)>
+        {
+            typedef typename Pair::second_type type;
+        };
+
+        template<typename This, typename Pair>
+        struct result<This(Pair &)>
+        {
+            typedef typename Pair::second_type &type;
+        };
+
+        template<typename This, typename Pair>
+        struct result<This(Pair const &)>
+        {
+            typedef typename Pair::second_type const &type;
+        };
+
+        template<typename Pair>
+        typename Pair::second_type &operator()(Pair &pair) const
+        {
+            return pair.second;
+        }
+
+        template<typename Pair>
+        typename Pair::second_type const &operator()(Pair const &pair) const
+        {
+            return pair.second;
+        }
+    };
+
+}}}
+
+#endif
Modified: trunk/boost/proto/fusion.hpp
==============================================================================
--- trunk/boost/proto/fusion.hpp	(original)
+++ trunk/boost/proto/fusion.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -18,8 +18,6 @@
 #include <boost/fusion/include/category_of.hpp>
 #include <boost/fusion/include/iterator_base.hpp>
 #include <boost/fusion/include/intrinsic.hpp>
-#include <boost/fusion/include/pop_front.hpp>
-#include <boost/fusion/include/reverse.hpp>
 #include <boost/fusion/include/single_view.hpp>
 #include <boost/fusion/include/transform_view.hpp>
 #include <boost/fusion/support/ext_/is_segmented.hpp>
@@ -29,6 +27,7 @@
 #include <boost/proto/proto_fwd.hpp>
 #include <boost/proto/traits.hpp>
 #include <boost/proto/eval.hpp>
+#include <boost/proto/functional/fusion.hpp>
 
 #if BOOST_MSVC
 #pragma warning(push)
@@ -39,10 +38,8 @@
 
 namespace boost { namespace proto
 {
-
     namespace detail
     {
-
         template<typename Expr, long Pos>
         struct expr_iterator
           : fusion::iterator_base<expr_iterator<Expr, Pos> >
@@ -171,92 +168,6 @@
                 return proto::detail::flat_view<Expr const>(e);
             }
         };
-
-        /// \brief A PolymorphicFunctionObject type that invokes the
-        /// \c fusion::pop_front() algorithm on its argument.
-        ///
-        /// A PolymorphicFunctionObject type that invokes the
-        /// \c fusion::pop_front() algorithm on its argument. This is
-        /// useful for defining a CallableTransform like \c pop_front(_)
-        /// which removes the first child from a Proto expression node.
-        /// Such a transform might be used as the first argument to the
-        /// \c proto::fold\<\> transform; that is, fold all but
-        /// the first child.
-        struct pop_front
-        {
-            BOOST_PROTO_CALLABLE()
-
-            template<typename Sig>
-            struct result;
-
-            template<typename This, typename Expr>
-            struct result<This(Expr)>
-              : result<This(Expr const &)>
-            {};
-
-            template<typename This, typename Expr>
-            struct result<This(Expr &)>
-              : fusion::result_of::pop_front<Expr>
-            {};
-
-            template<typename Expr>
-            typename fusion::result_of::pop_front<Expr>::type
-            operator ()(Expr &e) const
-            {
-                // Work around a const-correctness issue in Fusion
-                typedef typename fusion::result_of::pop_front<Expr>::type result_type;
-                return result_type(fusion::next(fusion::begin(e)), fusion::end(e));
-            }
-
-            template<typename Expr>
-            typename fusion::result_of::pop_front<Expr const>::type
-            operator ()(Expr const &e) const
-            {
-                return fusion::pop_front(e);
-            }
-        };
-
-        /// \brief A PolymorphicFunctionObject type that invokes the
-        /// \c fusion::reverse() algorithm on its argument.
-        ///
-        /// A PolymorphicFunctionObject type that invokes the
-        /// \c fusion::reverse() algorithm on its argument. This is
-        /// useful for defining a CallableTransform like \c reverse(_)
-        /// which reverses the order of the children of a Proto
-        /// expression node.
-        struct reverse
-        {
-            BOOST_PROTO_CALLABLE()
-
-            template<typename Sig>
-            struct result;
-
-            template<typename This, typename Expr>
-            struct result<This(Expr)>
-              : result<This(Expr const &)>
-            {};
-
-            template<typename This, typename Expr>
-            struct result<This(Expr &)>
-              : fusion::result_of::reverse<Expr>
-            {};
-
-            template<typename Expr>
-            typename fusion::result_of::reverse<Expr>::type
-            operator ()(Expr &e) const
-            {
-                // Work around a const-correctness issue in Fusion
-                typedef typename fusion::result_of::reverse<Expr>::type result_type;
-                return result_type(e);
-            }
-
-            template<typename Expr>
-            typename fusion::result_of::reverse<Expr const>::type
-            operator ()(Expr const &e) const
-            {
-                return fusion::reverse(e);
-            }
-        };
     }
 
     /// \brief A function that returns a "flattened"
@@ -288,29 +199,9 @@
 
     /// INTERNAL ONLY
     ///
-    template<>
-    struct is_callable<functional::flatten>
-      : mpl::true_
-    {};
-
-    /// INTERNAL ONLY
-    ///
-    template<>
-    struct is_callable<functional::pop_front>
-      : mpl::true_
-    {};
-
-    /// INTERNAL ONLY
-    ///
-    template<>
-    struct is_callable<functional::reverse>
-      : mpl::true_
-    {};
-
-    /// INTERNAL ONLY
-    ///
     template<typename Context>
     struct eval_fun
+      : proto::callable
     {
         explicit eval_fun(Context &ctx)
           : ctx_(ctx)
@@ -346,6 +237,13 @@
     private:
         Context &ctx_;
     };
+
+    /// INTERNAL ONLY
+    ///
+    template<typename Context>
+    struct is_callable<eval_fun<Context> >
+      : mpl::true_
+    {};
 }}
 
 namespace boost { namespace fusion
Modified: trunk/boost/proto/make_expr.hpp
==============================================================================
--- trunk/boost/proto/make_expr.hpp	(original)
+++ trunk/boost/proto/make_expr.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -53,19 +53,6 @@
     # pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored
     #endif
 
-    namespace boost
-    {
-        /// INTERNAL ONLY
-        ///
-        namespace fusion
-        {
-            /// INTERNAL ONLY
-            ///
-            template<typename Function>
-            class unfused_generic;
-        }
-    }
-
     namespace boost { namespace proto
     {
     /// INTERNAL ONLY
@@ -481,8 +468,7 @@
                 BOOST_PROTO_CALLABLE()
 
                 template<typename Sig>
-                struct result
-                {};
+                struct result;
 
                 template<typename This, typename Sequence>
                 struct result<This(Sequence)>
@@ -514,50 +500,6 @@
                 }
             };
 
-            /// INTERNAL ONLY
-            ///
-            template<typename Tag, typename Domain>
-            struct unfused_expr_fun
-            {
-                BOOST_PROTO_CALLABLE()
-
-                template<typename Sig>
-                struct result;
-
-                template<typename This, typename Sequence>
-                struct result<This(Sequence)>
-                {
-                    typedef
-                        typename result_of::unpack_expr<
-                            Tag
-                          , Domain
-                          , typename remove_reference<Sequence>::type
-                        >::type
-                    type;
-                };
-
-                template<typename Sequence>
-                typename proto::result_of::unpack_expr<Tag, Domain, Sequence const>::type const
-                operator ()(Sequence const &sequence) const
-                {
-                    return proto::detail::unpack_expr_<
-                        Tag
-                      , Domain
-                      , Sequence const
-                      , fusion::result_of::size<Sequence>::type::value
-                    >::call(sequence);
-                }
-            };
-
-            /// INTERNAL ONLY
-            ///
-            template<typename Tag, typename Domain>
-            struct unfused_expr
-              : fusion::unfused_generic<unfused_expr_fun<Tag, Domain> >
-            {
-                BOOST_PROTO_CALLABLE()
-            };
-
         } // namespace functional
 
         /// \brief Construct an expression of the requested tag type
@@ -693,13 +635,6 @@
           : mpl::true_
         {};
 
-        /// INTERNAL ONLY
-        ///
-        template<typename Tag, typename Domain>
-        struct is_callable<functional::unfused_expr<Tag, Domain> >
-          : mpl::true_
-        {};
-
     }}
 
     #ifdef _MSC_VER
Modified: trunk/boost/proto/matches.hpp
==============================================================================
--- trunk/boost/proto/matches.hpp	(original)
+++ trunk/boost/proto/matches.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -925,6 +925,13 @@
           : mpl::true_
         {};
 
+        /// INTERNAL ONLY
+        ///
+        template<typename Cases>
+        struct is_callable<switch_<Cases> >
+          : mpl::true_
+        {};
+
     }}
 
     #if defined(_MSC_VER) && (_MSC_VER >= 1020)
Modified: trunk/boost/proto/proto.hpp
==============================================================================
--- trunk/boost/proto/proto.hpp	(original)
+++ trunk/boost/proto/proto.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -13,5 +13,6 @@
 #include <boost/proto/debug.hpp>
 #include <boost/proto/context.hpp>
 #include <boost/proto/transform.hpp>
+#include <boost/proto/functional.hpp>
 
 #endif
Modified: trunk/boost/proto/proto_fwd.hpp
==============================================================================
--- trunk/boost/proto/proto_fwd.hpp	(original)
+++ trunk/boost/proto/proto_fwd.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -525,12 +525,6 @@
         template<typename Tag, typename Domain = deduce_domain>
         struct unpack_expr;
 
-        template<typename Tag, typename Domain = deduce_domain>
-        struct unfused_expr_fun;
-
-        template<typename Tag, typename Domain = deduce_domain>
-        struct unfused_expr;
-
         typedef make_expr<tag::terminal>            make_terminal;
         typedef make_expr<tag::unary_plus>          make_unary_plus;
         typedef make_expr<tag::negate>              make_negate;
@@ -638,10 +632,10 @@
     struct is_callable;
 
     template<typename T, typename Void = void>
-    struct is_aggregate;
+    struct is_transform;
 
     template<typename T, typename Void = void>
-    struct is_transform;
+    struct is_aggregate;
 
     #define BOOST_PROTO_UNEXPR() typedef int proto_is_expr_;
     #define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
@@ -655,7 +649,7 @@
 
     struct external_transform;
 
-    template<typename PrimitiveTransform, typename X = void>
+    template<typename PrimitiveTransform = void, typename X = void>
     struct transform;
 
     template<typename Grammar, typename Fun = Grammar>
Modified: trunk/boost/proto/traits.hpp
==============================================================================
--- trunk/boost/proto/traits.hpp	(original)
+++ trunk/boost/proto/traits.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -66,6 +66,7 @@
             struct is_callable_
               : is_callable2_<T>
             {};
+
         }
 
         /// \brief Boolean metafunction which detects whether a type is
@@ -107,6 +108,13 @@
           : mpl::false_
         {};
 
+        /// INTERNAL ONLY
+        ///
+        template<typename PrimitiveTransform, typename X>
+        struct is_callable<proto::transform<PrimitiveTransform, X> >
+          : mpl::false_
+        {};
+
         #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
         // work around GCC bug
         template<typename Tag, typename Args, long N>
@@ -121,6 +129,31 @@
         {};
         #endif
 
+        /// \brief Boolean metafunction which detects whether a type is
+        /// a PrimitiveTransform type or not.
+        ///
+        /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform
+        /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>,
+        /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data
+        /// parameters (as needed).
+        ///
+        /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt>
+        /// is computed as follows:
+        ///
+        /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef
+        /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is
+        /// the case for any type that derives from an instantiation of \c proto::transform.)
+        /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false.
+        template<typename T, typename Void /*= void*/>
+        struct is_transform
+          : mpl::false_
+        {};
+
+        template<typename T>
+        struct is_transform<T, typename T::proto_is_transform_>
+          : mpl::true_
+        {};
+
         /// \brief A Boolean metafunction that indicates whether a type requires
         /// aggregate initialization.
         ///
@@ -153,17 +186,6 @@
           : mpl::true_
         {};
 
-        /// TODO document me!
-        template<typename T, typename Void /* = void*/>
-        struct is_transform
-          : mpl::false_
-        {};
-
-        template<typename T>
-        struct is_transform<T, typename T::proto_is_transform_>
-          : mpl::true_
-        {};
-
         /// \brief A Boolean metafunction that indicates whether a given
         /// type \c T is a Proto expression type.
         ///
Modified: trunk/boost/proto/transform/default.hpp
==============================================================================
--- trunk/boost/proto/transform/default.hpp	(original)
+++ trunk/boost/proto/transform/default.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -81,7 +81,7 @@
                                                                                                         \
             template<typename Grammar>                                                                  \
             struct default_case<Grammar, tag::TAG>                                                      \
-            : when<unary_expr<tag::TAG, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> >                \
+              : when<unary_expr<tag::TAG, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> >              \
             {};                                                                                         \
             /**/
 
Modified: trunk/boost/proto/transform/fold_tree.hpp
==============================================================================
--- trunk/boost/proto/transform/fold_tree.hpp	(original)
+++ trunk/boost/proto/transform/fold_tree.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -176,6 +176,7 @@
     struct is_callable<reverse_fold_tree<Sequence, State0, Fun> >
       : mpl::true_
     {};
+
 }}
 
 #endif
Modified: trunk/boost/proto/transform/make.hpp
==============================================================================
--- trunk/boost/proto/transform/make.hpp	(original)
+++ trunk/boost/proto/transform/make.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -61,13 +61,6 @@
             {};
 
             template<typename R, typename Expr, typename State, typename Data
-                // BUGBUG this should be is_transform, but if R is a template instantiation
-                // it will cause the template to be instantiated, whereas is_callable will not.
-              , bool IsTransform = is_callable<R>::value
-            >
-            struct make_if_;
-
-            template<typename R, typename Expr, typename State, typename Data
                 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
             >
             struct make_
@@ -76,6 +69,28 @@
                 typedef void not_applied_;
             };
 
+            template<typename R, typename Expr, typename State, typename Data
+              , bool IsTransform = is_transform<R>::value
+            >
+            struct make_if2_
+              : make_<R, Expr, State, Data>
+            {};
+
+            template<typename R, typename Expr, typename State, typename Data>
+            struct make_if2_<R, Expr, State, Data, true>
+              : uncvref<typename R::template impl<Expr, State, Data>::result_type>
+            {};
+
+            template<typename R, typename Expr, typename State, typename Data
+                // HACKHACK This should really be is_transform; however, is_transform
+                // would have the unfortunate side-effect of instantiating R which is
+                // not acceptable in this context. Instead, we first check to see if 
+                // R is callable, which will not instantiate R. If is_callable is true,
+                // it is safe to instantiate R to check if it is a transform.
+              , bool IsCallable = is_callable<R>::value
+            >
+            struct make_if_;
+
             template<typename R, typename Expr, typename State, typename Data>
             struct make_if_<R, Expr, State, Data, false>
               : make_<R, Expr, State, Data>
@@ -99,10 +114,9 @@
             };
             #endif
 
-            // TODO could optimize this if R is a transform
             template<typename R, typename Expr, typename State, typename Data>
             struct make_if_<R, Expr, State, Data, true>
-              : uncvref<typename R::template impl<Expr, State, Data>::result_type>
+              : make_if2_<R, Expr, State, Data>
             {};
 
             template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
@@ -272,6 +286,7 @@
         struct is_callable<protect<PrimitiveTransform> >
           : mpl::true_
         {};
+
     }}
 
     #endif
@@ -397,7 +412,6 @@
             {
                 /// \brief <tt>boost::result_of\<make\<Object\>(Expr, State, Data)\>::type</tt>
                 typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
-                //typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
 
                 /// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt>
                 /// for each \c x in <tt>[0,N]</tt>.
Modified: trunk/boost/proto/transform/when.hpp
==============================================================================
--- trunk/boost/proto/transform/when.hpp	(original)
+++ trunk/boost/proto/transform/when.hpp	2010-11-28 00:04:50 EST (Sun, 28 Nov 2010)
@@ -186,6 +186,13 @@
         #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/when.hpp>))
         #include BOOST_PP_ITERATE()
 
+        /// INTERNAL ONLY
+        ///
+        template<typename Grammar, typename Transform>
+        struct is_callable<when<Grammar, Transform> >
+          : mpl::true_
+        {};
+
     }} // namespace boost::proto
 
     #endif