call.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 526 行 · 第 1/2 页
HPP
526 行
#ifndef BOOST_PP_IS_ITERATING /////////////////////////////////////////////////////////////////////////////// /// \file call.hpp /// Contains definition of the call<> transform. // // Copyright 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 BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007 #define BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007 #include <boost/xpressive/proto/detail/prefix.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/iteration/iterate.hpp> #include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/enum_trailing_params.hpp> #include <boost/utility/result_of.hpp> #include <boost/xpressive/proto/proto_fwd.hpp> #include <boost/xpressive/proto/traits.hpp> #include <boost/xpressive/proto/detail/dont_care.hpp> #include <boost/xpressive/proto/detail/as_lvalue.hpp> #include <boost/xpressive/proto/detail/suffix.hpp> namespace boost { namespace proto { namespace transform { namespace detail { using proto::detail::uncv; using proto::detail::as_lvalue; using proto::detail::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 callable0_wrap : Fun { callable0_wrap(); typedef private_type_ const &(*pfun0)(); operator pfun0() const; }; template<typename Fun> struct callable1_wrap : Fun { callable1_wrap(); typedef private_type_ const &(*pfun1)(dont_care); operator pfun1() const; }; template<typename Fun> struct callable2_wrap : Fun { callable2_wrap(); typedef private_type_ const &(*pfun2)(dont_care, dont_care); operator pfun2() const; }; template<typename Fun> struct arity0 { static callable0_wrap<Fun> &fun; static int const value = sizeof(yes_type) == sizeof(check_fun_arity((fun(), 0))) ? 0 : 3; }; template<typename Fun, typename A0> struct arity1 { static callable1_wrap<Fun> &fun; static A0 &a0; static int const value = sizeof(yes_type) == sizeof(check_fun_arity((fun(a0), 0))) ? 1 : 3; }; template<typename Fun, typename A0, typename A1> struct arity2 { static callable2_wrap<Fun> &fun; static A0 &a0; static A1 &a1; static int const value = sizeof(yes_type) == sizeof(check_fun_arity((fun(a0, a1), 0))) ? 2 : 3; }; template<typename Fun, typename Expr, typename State, typename Visitor> struct call3 { typedef typename boost::result_of<Fun(Expr, State, Visitor)>::type type; template<typename Expr2, typename State2, typename Visitor2> static type call(Expr2 &expr, State2 &state, Visitor2 &visitor) { Fun f; return f(expr, state, visitor); } }; template<typename Fun, typename Expr, typename State, typename Visitor , int Arity = arity0<Fun>::value> struct call0 : call3<Fun, Expr, State, Visitor> {}; template<typename Fun, typename Expr, typename State, typename Visitor> struct call0<Fun, Expr, State, Visitor, 0> { typedef typename boost::result_of<Fun()>::type type; template<typename Expr2, typename State2, typename Visitor2> static type call(Expr2 &, State2 &, Visitor2 &) { Fun f; return f(); } }; template<typename Fun, typename Expr, typename State, typename Visitor , int Arity = arity1<Fun, Expr>::value> struct call1 : call3<Fun, Expr, State, Visitor> {}; template<typename Fun, typename Expr, typename State, typename Visitor> struct call1<Fun, Expr, State, Visitor, 1> { typedef typename boost::result_of<Fun(Expr)>::type type; template<typename Expr2, typename State2, typename Visitor2> static type call(Expr2 &expr, State2 &, Visitor2 &) { Fun f; return f(expr); } }; template<typename Fun, typename Expr, typename State, typename Visitor , int Arity = arity2<Fun, Expr, State>::value> struct call2 : call3<Fun, Expr, State, Visitor> {}; template<typename Fun, typename Expr, typename State, typename Visitor> struct call2<Fun, Expr, State, Visitor, 2> { typedef typename boost::result_of<Fun(Expr, State)>::type type; template<typename Expr2, typename State2, typename Visitor2> static type call(Expr2 &expr, State2 &state, Visitor2 &) { Fun f; return f(expr, state); } }; } // namespace detail /// \brief Wrap \c PrimitiveTransform so that <tt>when\<\></tt> knows /// it is callable. Requires that the parameter is actually a /// PrimitiveTransform. /// /// This form of <tt>call\<\></tt> is useful for annotating an /// arbitrary PrimitiveTransform as callable when using it with /// <tt>when\<\></tt>. Consider the following transform, which /// is parameterized with another transform. /// /// \code /// template<typename Grammar> /// struct Foo /// : when< /// posit<Grammar> /// , Grammar(_arg) // May or may not work. /// > /// {}; /// \endcode /// /// The problem with the above is that <tt>when\<\></tt> may or /// may not recognize \c Grammar as callable, depending on how /// \c Grammar is implemented. (See <tt>is_callable\<\></tt> for /// a discussion of this issue.) The above code can guard against /// the issue by wrapping \c Grammar in <tt>call\<\></tt>, such /// as: /// /// \code /// template<typename Grammar> /// struct Foo /// : when< /// posit<Grammar> /// , call<Grammar>(_arg) // OK, this works /// > /// {}; /// \endcode /// /// The above could also have been written as: /// /// \code /// template<typename Grammar> /// struct Foo /// : when< /// posit<Grammar> /// , call<Grammar(_arg)> // OK, this works, too /// > /// {}; /// \endcode template<typename PrimitiveTransform> struct call : PrimitiveTransform { BOOST_PROTO_CALLABLE() }; /// \brief Either call the PolymorphicFunctionObject with 0 /// arguments, or invoke the PrimitiveTransform with 3 /// arguments. template<typename Fun> struct call<Fun()> : proto::callable { template<typename Sig> struct result; template<typename This, typename Expr, typename State, typename Visitor> struct result<This(Expr, State, Visitor)> { /// If \c Fun is a nullary PolymorphicFunctionObject, \c type is a typedef /// for <tt>boost::result_of\<Fun()\>::::type</tt>. Otherwise, it is /// a typedef for <tt>boost::result_of\<Fun(Expr, State, Visitor)\>::::type</tt>. typedef typename detail::call0< Fun , Expr , State , Visitor >::type type; }; /// Either call the PolymorphicFunctionObject \c Fun with 0 arguments; or /// invoke the PrimitiveTransform \c Fun with 3 arguments: the current /// expression, state, and visitor. /// /// If \c Fun is a nullary PolymorphicFunctionObject, return <tt>Fun()()</tt>.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?