Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53421 - in trunk/boost/proto: detail transform
From: eric_at_[hidden]
Date: 2009-05-29 19:49:45


Author: eric_niebler
Date: 2009-05-29 19:49:44 EDT (Fri, 29 May 2009)
New Revision: 53421
URL: http://svn.boost.org/trac/boost/changeset/53421

Log:
better compile-time performance of callable transforms
Text files modified:
   trunk/boost/proto/detail/poly_function.hpp | 40 ++++++++++++++++++++++++++++++++++++----
   trunk/boost/proto/transform/call.hpp | 25 ++++++++++---------------
   2 files changed, 46 insertions(+), 19 deletions(-)

Modified: trunk/boost/proto/detail/poly_function.hpp
==============================================================================
--- trunk/boost/proto/detail/poly_function.hpp (original)
+++ trunk/boost/proto/detail/poly_function.hpp 2009-05-29 19:49:44 EDT (Fri, 29 May 2009)
@@ -173,8 +173,32 @@
             #include BOOST_PP_ITERATE()
         };
 
+ typedef char poly_function_t;
+ typedef char (&mono_function_t)[2];
+ typedef char (&unknown_function_t)[3];
+
+ template<typename T> poly_function_t test_poly_function(T *, typename T::is_poly_function_base_ * = 0);
+ template<typename T> mono_function_t test_poly_function(T *, typename T::result_type * = 0);
+ template<typename T> unknown_function_t test_poly_function(T *, ...);
+
         ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename PolyFunSig, bool IsPoly>
+ template<typename Fun, typename Sig, std::size_t Switch = sizeof(test_poly_function<Fun>(0,0))>
+ struct poly_function_traits
+ {
+ typedef typename Fun::template result<Sig>::type result_type;
+ typedef Fun function_type;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Fun, typename Sig>
+ struct poly_function_traits<Fun, Sig, sizeof(mono_function_t)>
+ {
+ typedef typename Fun::result_type result_type;
+ typedef Fun function_type;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename PolyFunSig, bool IsPolyFunction>
         struct as_mono_function_impl;
 
         ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -237,21 +261,29 @@
     #define N BOOST_PP_ITERATION()
 
         ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
+ template<typename PolyFun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct poly_function_traits<PolyFun, PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), sizeof(poly_function_t)>
+ {
+ typedef typename PolyFun::template impl<BOOST_PP_ENUM_PARAMS(N, const A)> function_type;
+ typedef typename function_type::result_type result_type;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename PolyFun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
         struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), true>
         {
             typedef typename PolyFun::template impl<BOOST_PP_ENUM_PARAMS(N, const A)> type;
         };
 
         ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
+ template<typename PolyFun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
         struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), false>
         {
             typedef PolyFun type;
         };
 
         ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
+ template<typename PolyFun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
         struct as_mono_function<PolyFun(BOOST_PP_ENUM_PARAMS(N, A))>
           : as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), is_poly_function<PolyFun>::value>
         {};

Modified: trunk/boost/proto/transform/call.hpp
==============================================================================
--- trunk/boost/proto/transform/call.hpp (original)
+++ trunk/boost/proto/transform/call.hpp 2009-05-29 19:49:44 EDT (Fri, 29 May 2009)
@@ -143,15 +143,14 @@
               : transform_impl<Expr, State, Data>
             {
                 typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
- typedef typename detail::as_mono_function<Fun(a0)>::type mono_fun;
- typedef typename boost::result_of<mono_fun(a0)>::type result_type;
+ typedef typename detail::poly_function_traits<Fun, Fun(a0)>::result_type result_type;
                 result_type operator ()(
                     typename impl2::expr_param e
                   , typename impl2::state_param s
                   , typename impl2::data_param d
                 ) const
                 {
- return mono_fun()(
+ return typename detail::poly_function_traits<Fun, Fun(a0)>::function_type()(
                         detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
                     );
                 }
@@ -214,15 +213,14 @@
             {
                 typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
                 typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
- typedef typename detail::as_mono_function<Fun(a0, a1)>::type mono_fun;
- typedef typename boost::result_of<mono_fun(a0, a1)>::type result_type;
+ typedef typename detail::poly_function_traits<Fun, Fun(a0, a1)>::result_type result_type;
                 result_type operator ()(
                     typename impl2::expr_param e
                   , typename impl2::state_param s
                   , typename impl2::data_param d
                 ) const
                 {
- return mono_fun()(
+ return typename detail::poly_function_traits<Fun, Fun(a0, a1)>::function_type()(
                         detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
                       , detail::as_lvalue(typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d))
                     );
@@ -295,15 +293,14 @@
                 typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
                 typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
                 typedef typename when<_, A2>::template impl<Expr, State, Data>::result_type a2;
- typedef typename detail::as_mono_function<Fun(a0, a1, a2)>::type mono_fun;
- typedef typename boost::result_of<mono_fun(a0, a1, a2)>::type result_type;
+ typedef typename detail::poly_function_traits<Fun, Fun(a0, a1, a2)>::result_type result_type;
                 result_type operator ()(
                     typename impl2::expr_param e
                   , typename impl2::state_param s
                   , typename impl2::data_param d
                 ) const
                 {
- return mono_fun()(
+ return typename detail::poly_function_traits<Fun, Fun(a0, a1, a2)>::function_type()(
                         detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
                       , detail::as_lvalue(typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d))
                       , detail::as_lvalue(typename when<_, A2>::template impl<Expr, State, Data>()(e, s, d))
@@ -388,11 +385,7 @@
                 #undef M0
 
                 typedef
- typename detail::as_mono_function<Fun(BOOST_PP_ENUM_PARAMS(N, a))>::type
- mono_fun;
-
- typedef
- typename boost::result_of<mono_fun(BOOST_PP_ENUM_PARAMS(N, a))>::type
+ typename detail::poly_function_traits<Fun, Fun(BOOST_PP_ENUM_PARAMS(N, a))>::result_type
                 result_type;
 
                 /// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt>
@@ -413,7 +406,9 @@
                             typename when<_, BOOST_PP_CAT(A, M)> \
                                 ::template impl<Expr, State, Data>()(e, s, d)) \
                         /**/
- return mono_fun()(BOOST_PP_ENUM(N, M0, ~));
+ return typename detail::poly_function_traits<Fun, Fun(BOOST_PP_ENUM_PARAMS(N, a))>::function_type()(
+ BOOST_PP_ENUM(N, M0, ~)
+ );
                     #undef M0
                 }
             };


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