action_matcher.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 490 行 · 第 1/2 页

HPP
490
字号
///////////////////////////////////////////////////////////////////////////////// action_matcher.hpp////  Copyright 2008 Eric Niebler.//  Copyright 2008 David Jenkins.////  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_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005// MS compatible compilers support #pragma once#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif#include <boost/config.hpp>#include <boost/version.hpp>#include <boost/ref.hpp>#include <boost/assert.hpp>#include <boost/mpl/if.hpp>#include <boost/throw_exception.hpp>#include <boost/type_traits/is_const.hpp>#include <boost/type_traits/remove_reference.hpp>#include <boost/xpressive/detail/detail_fwd.hpp>#include <boost/xpressive/detail/core/quant_style.hpp>#include <boost/xpressive/detail/core/action.hpp>#include <boost/xpressive/detail/core/state.hpp>#include <boost/xpressive/proto/proto.hpp>#include <boost/xpressive/proto/context.hpp>#include <boost/xpressive/match_results.hpp> // for type_info_less#include <boost/xpressive/detail/static/transforms/as_action.hpp> // for 'read_attr'#if BOOST_VERSION >= 103500# include <boost/xpressive/proto/fusion.hpp># include <boost/fusion/include/transform_view.hpp># include <boost/fusion/include/invoke.hpp># include <boost/fusion/include/push_front.hpp># include <boost/fusion/include/pop_front.hpp>#endif#if BOOST_MSVC#pragma warning(push)#pragma warning(disable : 4510) // default constructor could not be generated#pragma warning(disable : 4512) // assignment operator could not be generated#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required#endifnamespace boost { namespace xpressive { namespace detail{    #if BOOST_VERSION >= 103500    struct DataMember      : proto::mem_ptr<proto::_, proto::terminal<proto::_> >    {};    template<typename Expr, long N>    struct child_      : remove_reference<typename mpl::if_<            is_const<Expr>          , typename proto::result_of::arg_c<Expr, N>::const_reference          , typename proto::result_of::arg_c<Expr, N>::reference        >::type>    {};    ///////////////////////////////////////////////////////////////////////////////    // mem_ptr_eval    //  Rewrites expressions of the form x->*foo(a) into foo(x, a) and then    //  evaluates them.    template<typename Expr, typename Context, bool IsDataMember = proto::matches<Expr, DataMember>::value>    struct mem_ptr_eval    {        typedef typename child_<Expr, 0>::type left_type;        typedef typename child_<Expr, 1>::type right_type;        typedef            typename proto::result_of::arg<                typename proto::result_of::arg_c<right_type, 0>::type            >::type        function_type;        typedef            fusion::transform_view<                typename fusion::result_of::push_front<                    typename fusion::result_of::pop_front<right_type>::type const                  , reference_wrapper<left_type>                >::type const              , proto::eval_fun<Context>            >        evaluated_args;        typedef            typename fusion::result_of::invoke<function_type, evaluated_args>::type        result_type;        result_type operator()(Expr &expr, Context &ctx) const        {            return fusion::invoke<function_type>(                proto::arg(proto::arg_c<0>(proto::right(expr)))              , evaluated_args(                    fusion::push_front(fusion::pop_front(proto::right(expr)), boost::ref(proto::left(expr)))                  , proto::eval_fun<Context>(ctx)                )            );        }    };    ///////////////////////////////////////////////////////////////////////////////    // mem_ptr_eval    //  Rewrites expressions of the form x->*foo into foo(x) and then    //  evaluates them.    template<typename Expr, typename Context>    struct mem_ptr_eval<Expr, Context, true>    {        typedef typename child_<Expr, 0>::type left_type;        typedef typename child_<Expr, 1>::type right_type;        typedef            typename proto::result_of::arg<right_type>::type        function_type;        typedef typename boost::result_of<            function_type(typename proto::result_of::eval<left_type, Context>::type)        >::type result_type;        result_type operator()(Expr &expr, Context &ctx) const        {            return proto::arg(proto::right(expr))(                proto::eval(proto::left(expr), ctx)            );        }    };    #endif    struct attr_with_default_tag    {};    template<typename T>    struct opt;    ///////////////////////////////////////////////////////////////////////////////    // action_context    //    struct action_context    {        explicit action_context(action_args_type *action_args)          : action_args_(action_args)        {}        action_args_type const &args() const        {            return *this->action_args_;        }        // eval_terminal        template<typename Expr, typename Arg>        struct eval_terminal          : proto::default_eval<Expr, action_context const>        {};        template<typename Expr, typename Arg>        struct eval_terminal<Expr, reference_wrapper<Arg> >        {            typedef Arg &result_type;            result_type operator()(Expr &expr, action_context const &) const            {                return proto::arg(expr).get();            }        };        template<typename Expr, typename Arg>        struct eval_terminal<Expr, opt<Arg> >        {            typedef Arg const &result_type;            result_type operator()(Expr &expr, action_context const &) const            {                return proto::arg(expr);            }        };        template<typename Expr, typename Type, typename Int>        struct eval_terminal<Expr, action_arg<Type, Int> >        {            typedef typename action_arg<Type, Int>::reference result_type;            result_type operator()(Expr &expr, action_context const &ctx) const            {                action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::arg(expr)));                if(where_ == ctx.args().end())                {                    boost::throw_exception(                        regex_error(                            regex_constants::error_badarg                          , "An argument to an action was unspecified"                        )                    );                }                return proto::arg(expr).cast(where_->second);            }        };        // eval        template<typename Expr, typename Tag = typename Expr::proto_tag>        struct eval          : proto::default_eval<Expr, action_context const>        {};        template<typename Expr>        struct eval<Expr, proto::tag::terminal>          : eval_terminal<Expr, typename proto::result_of::arg<Expr>::type>        {};        // Evaluate attributes like a1|42        template<typename Expr>        struct eval<Expr, attr_with_default_tag>        {            typedef                typename proto::result_of::arg<                    typename proto::result_of::left<                        typename proto::result_of::arg<                            Expr                        >::type                    >::type                >::type            temp_type;            typedef typename temp_type::type result_type;            result_type operator ()(Expr const &expr, action_context const &ctx) const            {                return proto::arg(proto::left(proto::arg(expr))).t_                    ? *proto::arg(proto::left(proto::arg(expr))).t_                    :  proto::eval(proto::right(proto::arg(expr)), ctx);            }        };        #if BOOST_VERSION >= 103500        template<typename Expr>        struct eval<Expr, proto::tag::mem_ptr>          : mem_ptr_eval<Expr, action_context const>        {};        #endif    private:        action_args_type *action_args_;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?