Boost logo

Boost-Commit :

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


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk