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 + -
显示快捷键?