|
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