Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-06-03 12:40:21


Author: eric_niebler
Date: 2008-06-03 12:40:20 EDT (Tue, 03 Jun 2008)
New Revision: 46082
URL: http://svn.boost.org/trac/boost/changeset/46082

Log:
begin tweaks to improve compile times
Added:
   branches/proto/v4/boost/phoenix/core/as_actor.hpp (contents, props changed)
Text files modified:
   branches/proto/v4/boost/phoenix/core/actor.hpp | 194 ++++++++++++++++++++++++---------------
   branches/proto/v4/boost/phoenix/core/limits.hpp | 17 +-
   branches/proto/v4/boost/phoenix/operator/member.hpp | 189 ++++++++++++++++++++++++--------------
   3 files changed, 244 insertions(+), 156 deletions(-)

Modified: branches/proto/v4/boost/phoenix/core/actor.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/core/actor.hpp (original)
+++ branches/proto/v4/boost/phoenix/core/actor.hpp 2008-06-03 12:40:20 EDT (Tue, 03 Jun 2008)
@@ -28,6 +28,7 @@
     #include <boost/preprocessor.hpp>
     #include <boost/utility/result_of.hpp>
     #include <boost/fusion/include/vector.hpp>
+ #include <boost/phoenix/core/as_actor.hpp>
 
     namespace boost { namespace phoenix
     {
@@ -187,64 +188,25 @@
             {};
 
             ////////////////////////////////////////////////////////////////////////////////////////
- // These terminal types are always stored by reference
- template<typename Value>
- struct storage
- {
- typedef
- typename mpl::eval_if_c<
- mpl::or_<
- is_abstract<Value>
- , is_function<Value>
- , is_base_of<std::ios_base, Value>
- >::type::value
- , add_reference<Value>
- , remove_const<Value>
- >::type
- type;
- };
-
- template<typename T, std::size_t N>
- struct storage<T[N]>
- {
- typedef T (&type)[N];
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////
             // Store terminals by value, unless they are streams, arrays, functions or abstract types.
             struct generator
             {
                 template<typename Sig>
                 struct result;
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef actor<typename proto::by_value_generator::result<void(Expr)>::type> type;
- };
-
                 template<typename This, typename T>
                 struct result<This(proto::expr<proto::tag::terminal, proto::term<T &> >)>
                 {
                     typedef
                         actor<
- proto::expr<proto::tag::terminal, proto::term<typename storage<T>::type> >
+ proto::expr<proto::tag::terminal, proto::term<typename storage<T>::type>, 0>
>
                     type;
                 };
 
- template<typename Expr>
- actor<typename proto::by_value_generator::result<void(Expr)>::type> const
- operator()(Expr const &expr) const
- {
- actor<typename proto::by_value_generator::result<void(Expr)>::type> that
- = {proto::by_value_generator()(expr)};
- return that;
- }
-
                 template<typename T>
                 actor<
- proto::expr<proto::tag::terminal, proto::term<typename storage<T>::type> >
+ proto::expr<proto::tag::terminal, proto::term<typename storage<T>::type>, 0>
> const
                 operator()(proto::expr<proto::tag::terminal, proto::term<T &> > const &expr) const
                 {
@@ -256,6 +218,37 @@
> that = {{expr.child0}};
                     return that;
                 }
+
+ #if 1
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef actor<typename proto::by_value_generator::result<void(Expr)>::type> type;
+ };
+
+ template<typename Expr>
+ actor<typename proto::by_value_generator::result<void(Expr)>::type> const
+ operator()(Expr const &expr) const
+ {
+ actor<typename proto::by_value_generator::result<void(Expr)>::type> that
+ = {proto::by_value_generator()(expr)};
+ return that;
+ }
+ #else
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef actor<Expr> type;
+ };
+
+ template<typename Expr>
+ actor<Expr> const
+ operator()(Expr const &expr) const
+ {
+ actor<Expr> that = {expr};
+ return that;
+ }
+ #endif
             };
 
             ////////////////////////////////////////////////////////////////////////////////////////
@@ -298,6 +291,39 @@
             /**/
             BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(PHOENIX_LIMIT), M0, ~)
             #undef M0
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Result, typename Expr, typename Args>
+ Result evaluate(Expr &expr, Args &args, mpl::true_)
+ {
+ return evaluator<>()(expr.proto_base(), mpl::void_(), args);
+ }
+
+ template<typename Result, typename Expr, typename Args>
+ Result evaluate(Expr &, Args &, mpl::false_)
+ {
+ BOOST_ASSERT(false);
+ throw "never called";
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Result, typename Expr, typename Args>
+ Result evaluate(Expr &expr, Args &args)
+ {
+ typedef typename
+ mpl::if_<
+ proto::matches<Expr, evaluator<> >
+ , VALID_LAMBDA_EXPRESSION
+ , INVALID_LAMBDA_EXPRESSION
+ >::type
+ IS_VALID_LAMBDA_EXPRESSION;
+
+ // If your compile breaks here, your lambda expression doesn't validate against
+ // the Phoenix lambda grammar. Go back and check your expression for well-formedness.
+ BOOST_MPL_ASSERT((IS_VALID_LAMBDA_EXPRESSION));
+
+ return detail::evaluate<Result>(expr, args, IS_VALID_LAMBDA_EXPRESSION());
+ }
         }
 
         ////////////////////////////////////////////////////////////////////////////////////////////
@@ -317,20 +343,66 @@
             struct actor
             {
                 BOOST_PROTO_BASIC_EXTENDS(Expr, actor<Expr>, detail::domain)
- BOOST_PROTO_EXTENDS_ASSIGN()
- BOOST_PROTO_EXTENDS_SUBSCRIPT()
 
                 template<typename Sig>
                 struct result
                   : detail::result<Sig>
                 {};
+
+ template<typename A>
+ actor<
+ proto::expr<
+ proto::tag::assign
+ , proto::list2<
+ actor<Expr>
+ , typename as_actor<A const>::type
+ >
+ >
+ > const
+ operator =(A const &a) const
+ {
+ actor<
+ proto::expr<
+ proto::tag::assign
+ , proto::list2<
+ actor<Expr>
+ , typename as_actor<A const>::type
+ >
+ >
+ > that = {{*this, as_actor<A const>::convert(a)}};
+ return that;
+ }
+
+ template<typename A>
+ actor<
+ proto::expr<
+ proto::tag::subscript
+ , proto::list2<
+ actor<Expr>
+ , typename as_actor<A const>::type
+ >
+ >
+ > const
+ operator [](A const &a) const
+ {
+ actor<
+ proto::expr<
+ proto::tag::subscript
+ , proto::list2<
+ actor<Expr>
+ , typename as_actor<A const>::type
+ >
+ >
+ > that = {{*this, as_actor<A const>::convert(a)}};
+ return that;
+ }
 
                 typename result<Expr const()>::type
                 operator()() const
                 {
                     typedef typename result<Expr const()>::type result_type;
                     fusion::vector0 args;
- return this->evaluate<result_type>(args);
+ return detail::evaluate<result_type>(*this, args);
                 }
 
                 #define M0(Z, N, _) ((0))
@@ -349,7 +421,7 @@
                         result_type; \
                         BOOST_PP_CAT(fusion::vector, SIZE)<BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)> args \
                             (BOOST_PP_SEQ_FOR_EACH_I_R(R, M6, ~, PRODUCT)); \
- return this->evaluate<result_type>(args); \
+ return detail::evaluate<result_type>(*this, args); \
                     } \
                     /**/
 
@@ -381,38 +453,6 @@
                 #undef M4
                 #undef M5
                 #undef M6
-
- private:
- template<typename Result, typename Args>
- Result evaluate(Args &args) const
- {
- typedef typename
- mpl::if_<
- proto::matches<Expr, evaluator<> >
- , VALID_LAMBDA_EXPRESSION
- , INVALID_LAMBDA_EXPRESSION
- >::type
- IS_VALID_LAMBDA_EXPRESSION;
-
- // If your compile breaks here, your lambda expression doesn't validate against
- // the Phoenix lambda grammar. Go back and check your expression for well-formedness.
- BOOST_MPL_ASSERT((IS_VALID_LAMBDA_EXPRESSION));
-
- return this->evaluate<Result>(args, IS_VALID_LAMBDA_EXPRESSION());
- }
-
- template<typename Result, typename Args>
- Result evaluate(Args &args, mpl::true_) const
- {
- return evaluator<>()(this->proto_base(), mpl::void_(), args);
- }
-
- template<typename Result, typename Args>
- Result evaluate(Args &args, mpl::false_) const
- {
- BOOST_ASSERT(false);
- throw "never called";
- }
             };
 
         } // namespace actorns_

Added: branches/proto/v4/boost/phoenix/core/as_actor.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/phoenix/core/as_actor.hpp 2008-06-03 12:40:20 EDT (Tue, 03 Jun 2008)
@@ -0,0 +1,112 @@
+/*=============================================================================
+ Copyright (c) 2001-2007 Joel de Guzman
+
+ 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_PHOENIX_AS_ACTOR_HPP_EAN_2008_06_03
+#define BOOST_PHOENIX_AS_ACTOR_HPP_EAN_2008_06_03
+
+#include <iosfwd> // for std::ios_base
+#include <boost/mpl/or.hpp>
+#include <boost/proto/proto.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_abstract.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+namespace boost { namespace phoenix
+{
+ namespace actorns_
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Expr>
+ struct actor;
+ }
+
+ using actorns_::actor;
+
+ namespace detail
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // These terminal types are always stored by reference
+ template<typename Value>
+ struct storage
+ {
+ typedef
+ typename mpl::eval_if_c<
+ mpl::or_<
+ is_abstract<Value>
+ , is_function<Value>
+ , is_base_of<std::ios_base, Value>
+ >::type::value
+ , add_reference<Value>
+ , remove_const<Value>
+ >::type
+ type;
+ };
+
+ template<typename T, std::size_t N>
+ struct storage<T[N]>
+ {
+ typedef T (&type)[N];
+ };
+
+ template<typename T, std::size_t N>
+ struct storage<T const[N]>
+ {
+ typedef T const (&type)[N];
+ };
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T>
+ struct as_actor
+ {
+ typedef
+ proto::expr<
+ proto::tag::terminal
+ , proto::term<typename detail::storage<T>::type>
+ >
+ term_type;
+
+ typedef
+ actor<term_type>
+ type;
+
+ static type const
+ convert(T const &t)
+ {
+ return type::make(term_type::make(t));
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Expr>
+ struct as_actor<actor<Expr> >
+ {
+ typedef actor<Expr> type;
+
+ static actor<Expr> const
+ convert(actor<Expr> const &expr)
+ {
+ return expr;
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Expr>
+ struct as_actor<actor<Expr> const>
+ {
+ typedef actor<Expr> type;
+
+ static actor<Expr> const
+ convert(actor<Expr> const &expr)
+ {
+ return expr;
+ }
+ };
+}}
+
+#endif

Modified: branches/proto/v4/boost/phoenix/core/limits.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/core/limits.hpp (original)
+++ branches/proto/v4/boost/phoenix/core/limits.hpp 2008-06-03 12:40:20 EDT (Tue, 03 Jun 2008)
@@ -8,6 +8,7 @@
 #define PHOENIX_CORE_LIMITS_HPP
 
 #include <boost/preprocessor/selection/min.hpp>
+#include <boost/preprocessor/selection/max.hpp>
 
 #if !defined(PHOENIX_LIMIT)
 # define PHOENIX_LIMIT 10
@@ -18,19 +19,19 @@
 #endif
 
 #if !defined(PHOENIX_PERFECT_FORWARD_LIMIT)
-# define PHOENIX_PERFECT_FORWARD_LIMIT 3
+# define PHOENIX_PERFECT_FORWARD_LIMIT 0
 #endif
 
 #if !defined(PHOENIX_ACTOR_LIMIT)
 # define PHOENIX_ACTOR_LIMIT PHOENIX_LIMIT
 #elif (PHOENIX_ACTOR_LIMIT > PHOENIX_LIMIT)
-# error "PHOENIX_ACTOR_LIMIT is set too high"
+# error PHOENIX_ACTOR_LIMIT is set too high
 #endif
 
 #if !defined(FUSION_MAX_TUPLE_SIZE)
 # define FUSION_MAX_TUPLE_SIZE PHOENIX_LIMIT
 #elif (FUSION_MAX_TUPLE_SIZE < PHOENIX_LIMIT)
-# error "FUSION_MAX_TUPLE_SIZE is set too low"
+# error FUSION_MAX_TUPLE_SIZE is set too low
 #endif
 
 #if !defined(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY)
@@ -42,7 +43,7 @@
 # error BOOST_PROTO_MAX_ARITY must be at least as large as PHOENIX_LIMIT
 # endif
 #else
-# define BOOST_PROTO_MAX_ARITY PHOENIX_LIMIT
+# define BOOST_PROTO_MAX_ARITY BOOST_PP_MAX(PHOENIX_LIMIT, 5)
 #endif
 
 #if defined(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
@@ -50,12 +51,12 @@
 # error BOOST_MPL_LIMIT_METAFUNCTION_ARITY must be at least as large as PHOENIX_LIMIT
 # endif
 #else
-# define BOOST_MPL_LIMIT_METAFUNCTION_ARITY PHOENIX_LIMIT
+# define BOOST_MPL_LIMIT_METAFUNCTION_ARITY BOOST_PP_MAX(PHOENIX_LIMIT, 5)
 #endif
 
-// this include will bring in mpl::vectorN and
-// fusion::tupleN where N is PHOENIX_ACTOR_LIMIT
-#include <boost/fusion/include/vector.hpp>
+//// this include will bring in mpl::vectorN and
+//// fusion::tupleN where N is PHOENIX_ACTOR_LIMIT
+//#include <boost/fusion/include/vector.hpp>
 
 // OK, limits set. Include Proto.
 #include <boost/proto/proto.hpp>

Modified: branches/proto/v4/boost/phoenix/operator/member.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/operator/member.hpp (original)
+++ branches/proto/v4/boost/phoenix/operator/member.hpp 2008-06-03 12:40:20 EDT (Tue, 03 Jun 2008)
@@ -1,84 +1,131 @@
-/*=============================================================================
- Copyright (c) 2001-2007 Joel de Guzman
+#ifndef BOOST_PP_IS_ITERATING
+ /*=============================================================================
+ Copyright (c) 2001-2007 Joel de Guzman
+ Copyright (c) 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 PHOENIX_OPERATOR_MEMBER_HPP_EAN_2008_05_28
+ #define PHOENIX_OPERATOR_MEMBER_HPP_EAN_2008_05_28
+
+ #include <boost/ref.hpp>
+ #include <boost/preprocessor.hpp>
+ #include <boost/type_traits/is_member_function_pointer.hpp>
+ #include <boost/phoenix/core/actor.hpp>
+ #include <boost/proto/proto.hpp>
+
+ #if !defined(PHOENIX_MEMBER_LIMIT)
+ #define PHOENIX_MEMBER_LIMIT BOOST_PP_SUB(PHOENIX_LIMIT, 2)
+ #endif
 
- 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 PHOENIX_OPERATOR_MEMBER_HPP_EAN_2008_05_28
-#define PHOENIX_OPERATOR_MEMBER_HPP_EAN_2008_05_28
-
-#include <boost/ref.hpp>
-#include <boost/type_traits/is_member_object_pointer.hpp>
-#include <boost/type_traits/is_member_function_pointer.hpp>
-#include <boost/phoenix/core/actor.hpp>
-#include <boost/fusion/include/push_front.hpp>
-#include <boost/fusion/include/as_vector.hpp>
-#include <boost/proto/proto.hpp>
-
-namespace boost { namespace phoenix
-{
- namespace detail
+ namespace boost { namespace phoenix
     {
- ////////////////////////////////////////////////////////////////////////////////////////////
- template<typename SubGrammar, typename Callable = proto::callable>
- struct bind_mem_ptr
- : proto::transform<bind_mem_ptr<SubGrammar> >
+ namespace detail
         {
- template<typename Expr, typename State, typename Data>
- struct impl
- : proto::transform_impl<Expr, State, Data>
+ ////////////////////////////////////////////////////////////////////////////////////////
+ template<typename Object, typename MemPtr>
+ struct mem_ptr_gen
             {
- typedef typename
- proto::result_of::unpack_expr<
- proto::tag::function
- , domain
- , typename fusion::result_of::as_vector<
- typename fusion::result_of::push_front<
- typename fusion::result_of::push_front<
- typename impl::data
- , typename proto::result_of::left<Expr>::type
- >::type
- , typename proto::result_of::right<Expr>::type
- >::type
- >::type
- >::type
- result_type;
-
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param
- , typename impl::data_param data
- ) const
+ mem_ptr_gen(Object const &obj, MemPtr const &ptr)
+ : obj(obj)
+ , ptr(ptr)
+ {}
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ actor<typename proto::function<MemPtr, Object>::type> const
+ operator()() const
                 {
- return proto::unpack_expr<proto::tag::function, domain>(
- fusion::as_vector(
- fusion::push_front(
- fusion::push_front(
- data
- , boost::ref(proto::left(expr))
- )
- , boost::ref(proto::right(expr))
- )
+ typedef
+ typename proto::function<MemPtr, Object>::type
+ expr_type;
+
+ return actor<expr_type>::make(
+ expr_type::make(
+ this->ptr
+ , this->obj
                         )
                     );
                 }
+
+ #define M0(Z, N, DATA) \
+ typename as_actor<BOOST_PP_CAT(A, N) const>::type \
+ /**/
+
+ #define M1(Z, N, DATA) \
+ as_actor<BOOST_PP_CAT(A, N) const>::convert(BOOST_PP_CAT(a, N)) \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (1, PHOENIX_MEMBER_LIMIT, <boost/phoenix/operator/member.hpp>)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+
+ #undef M0
+ #undef M1
+
+ private:
+ Object obj;
+ MemPtr ptr;
             };
- };
- }
+ }
+
+ namespace actorns_
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // This operator overload is preferred to Proto's when the second parameter
+ // is a member function pointer. If it is a member object pointer, Proto's
+ // default handling will do the right thing.
+ template<typename Object, typename MemPtr>
+ typename enable_if<
+ is_member_function_pointer<MemPtr>
+ , detail::mem_ptr_gen<actor<Object>, typename proto::terminal<MemPtr>::type> const
+ >::type
+ operator->*(actor<Object> const &obj, MemPtr ptr)
+ {
+ typedef typename proto::terminal<MemPtr>::type mem_ptr_type;
+ return detail::mem_ptr_gen<actor<Object>, mem_ptr_type>(obj, mem_ptr_type::make(ptr));
+ }
+
+ } // namespace actorns_
 
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename SubGrammar>
- struct extension<proto::tag::mem_ptr, SubGrammar>
- : proto::when<
- proto::mem_ptr<evaluator<SubGrammar>, proto::terminal<proto::_> >
- , proto::if_<
- is_member_function_pointer<proto::_value(proto::_right)>()
- , detail::bind_mem_ptr<SubGrammar>
- , proto::_default<evaluator<SubGrammar> >
- >
- >
- {};
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ actor<
+ typename proto::function<
+ MemPtr
+ , Object
+ BOOST_PP_ENUM_TRAILING(N, M0, ~)
+ >::type
+ > const
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a)) const
+ {
+ typedef
+ typename proto::function<
+ MemPtr
+ , Object
+ BOOST_PP_ENUM_TRAILING(N, M0, ~)
+ >::type
+ expr_type;
+
+ return actor<expr_type>::make(
+ expr_type::make(
+ this->ptr
+ , this->obj
+ BOOST_PP_ENUM_TRAILING(N, M1, ~)
+ )
+ );
+ }
 
-}}
+ #undef N
 
 #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