Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2007-12-02 05:40:37


Author: eric_niebler
Date: 2007-12-02 05:40:35 EST (Sun, 02 Dec 2007)
New Revision: 41576
URL: http://svn.boost.org/trac/boost/changeset/41576

Log:
attempt to auto-detect the arity of function objects (experimental)
Text files modified:
   branches/proto/v3/boost/xpressive/proto/transform/call.hpp | 189 ++++++++++++++++++++++++++++++++++++++++
   1 files changed, 189 insertions(+), 0 deletions(-)

Modified: branches/proto/v3/boost/xpressive/proto/transform/call.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/call.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/call.hpp 2007-12-02 05:40:35 EST (Sun, 02 Dec 2007)
@@ -18,7 +18,108 @@
 
     namespace transform
     {
+ namespace detail
+ {
+ template<typename T>
+ T &uncv(T const &t)
+ {
+ return const_cast<T &>(t);
+ }
+
+ struct dont_care { dont_care(...); };
+
+ typedef char (&yes_type)[2];
+ typedef char no_type;
+
+ struct private_type_
+ {
+ private_type_ const &operator,(int) const;
+ };
+
+ template<typename T>
+ yes_type check_fun_arity(T const &);
+
+ no_type check_fun_arity(private_type_ const &);
 
+ template<typename Fun>
+ struct fun_wrap : Fun
+ {
+ fun_wrap();
+ typedef private_type_ const &(*pfun1)(dont_care);
+ typedef private_type_ const &(*pfun2)(dont_care, dont_care);
+ typedef private_type_ const &(*pfun3)(dont_care, dont_care, dont_care);
+ operator pfun1() const;
+ operator pfun2() const;
+ operator pfun3() const;
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor>
+ struct fun_arity
+ {
+ static fun_wrap<Fun> &fun_;
+ static Expr &expr_;
+ static State &state_;
+ static Visitor &visitor_;
+
+ static int const value =
+ (sizeof(check_fun_arity((fun_(expr_), 0)))-1)? 1 :
+ (sizeof(check_fun_arity((fun_(expr_, state_), 0)))-1)? 2 :
+ (sizeof(check_fun_arity((fun_(expr_, state_, visitor_), 0)))-1)? 3 :
+ -1;
+ };
+
+ template<
+ typename Fun
+ , typename Expr
+ , typename State
+ , typename Visitor
+ , int Needs
+ , int Arity =
+ (fun_arity<Fun, Expr, State, Visitor>::value > Needs) ?
+ fun_arity<Fun, Expr, State, Visitor>::value : Needs
+ >
+ struct call_;
+
+ template<typename Fun, typename Expr, typename State, typename Visitor, int Needs>
+ struct call_<Fun, Expr, State, Visitor, Needs, 1>
+ {
+ typedef typename boost::result_of<Fun(Expr)>::type type;
+
+ template<typename A, typename B, typename C>
+ static type call(A &&expr, B &&, C &&)
+ {
+ Fun f;
+ return f(expr);
+ }
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor, int Needs>
+ struct call_<Fun, Expr, State, Visitor, Needs, 2>
+ {
+ typedef typename boost::result_of<Fun(Expr, State)>::type type;
+
+ template<typename A, typename B, typename C>
+ static type call(A &&expr, B &&state, C &&)
+ {
+ Fun f;
+ return f(expr, state);
+ }
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor, int Needs>
+ struct call_<Fun, Expr, State, Visitor, Needs, 3>
+ {
+ typedef typename boost::result_of<Fun(Expr, State, Visitor)>::type type;
+
+ template<typename A, typename B, typename C>
+ static type call(A &&expr, B &&state, C &&visitor)
+ {
+ Fun f;
+ return f(expr, state, visitor);
+ }
+ };
+ }
+
         template<typename Fun, typename... Args>
         struct call : raw_transform
         {
@@ -40,6 +141,94 @@
                 return f(when<_, Args>()(expr, state, visitor)...);
             }
         };
+
+ template<typename Fun, typename Arg0>
+ struct call<Fun, Arg0> : raw_transform
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ : detail::call_<
+ Fun
+ , typename boost::result_of<when<_, Arg0>(Expr, State, Visitor)>::type
+ , State
+ , Visitor
+ , 1
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<call(Expr, State, Visitor)>::type
+ operator()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return result<call(Expr, State, Visitor)>::call(
+ when<_, Arg0>()(expr, state, visitor)
+ , state
+ , visitor
+ );
+ }
+ };
+
+ template<typename Fun, typename Arg0, typename Arg1>
+ struct call<Fun, Arg0, Arg1> : raw_transform
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ : detail::call_<
+ Fun
+ , typename boost::result_of<when<_, Arg0>(Expr, State, Visitor)>::type
+ , typename boost::result_of<when<_, Arg1>(Expr, State, Visitor)>::type
+ , Visitor
+ , 2
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<call(Expr, State, Visitor)>::type
+ operator()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return result<call(Expr, State, Visitor)>::call(
+ when<_, Arg0>()(expr, state, visitor)
+ , when<_, Arg1>()(expr, state, visitor)
+ , visitor
+ );
+ }
+ };
+
+ template<typename Fun, typename Arg0, typename Arg1, typename Arg2>
+ struct call<Fun, Arg0, Arg1, Arg2> : raw_transform
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ : boost::result_of<
+ Fun(
+ typename boost::result_of<when<_, Arg0>(Expr, State, Visitor)>::type
+ , typename boost::result_of<when<_, Arg1>(Expr, State, Visitor)>::type
+ , typename boost::result_of<when<_, Arg2>(Expr, State, Visitor)>::type
+ )
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<call(Expr, State, Visitor)>::type
+ operator()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ Fun f;
+ return f(
+ when<_, Arg0>()(expr, state, visitor)
+ , when<_, Arg1>()(expr, state, visitor)
+ , detail::uncv(when<_, Arg2>()(expr, state, visitor)) // HACK
+ );
+ }
+ };
 
         template<typename Fun, typename... Args>
         struct call<Fun(Args...)>


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