matches.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 996 行 · 第 1/3 页
HPP
996 行
typename Args1::BOOST_PP_CAT(arg, n)::proto_base_expr\ , typename Args2::BOOST_PP_CAT(arg, n)::proto_base_expr\ > #define BOOST_PROTO_DEFINE_MATCHES(z, n, data)\ matches_<\ typename Expr::proto_base_expr\ , typename BOOST_PP_CAT(G, n)::proto_base_expr\ > #define BOOST_PROTO_DEFINE_LAMBDA_MATCHES(z, n, data)\ lambda_matches<\ BOOST_PP_CAT(Expr, n)\ , BOOST_PP_CAT(Grammar, n)\ > #if BOOST_PROTO_MAX_LOGICAL_ARITY > BOOST_PROTO_MAX_ARITY #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_LOGICAL_ARITY, <boost/xpressive/proto/matches.hpp>, 1)) #else #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/matches.hpp>, 1)) #endif #include BOOST_PP_ITERATE() #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/matches.hpp>, 2)) #include BOOST_PP_ITERATE() #undef BOOST_PROTO_MATCHES_N_FUN #undef BOOST_PROTO_DEFINE_MATCHES #undef BOOST_PROTO_DEFINE_LAMBDA_MATCHES // handle proto::if_ template<typename Expr, typename If, typename Then, typename Else> struct matches_<Expr, proto::if_<If, Then, Else> > : mpl::eval_if< typename when<_, If>::template result<void(Expr, int, int)>::type , matches_<Expr, typename Then::proto_base_expr> , matches_<Expr, typename Else::proto_base_expr> >::type {}; template<typename Expr, typename If> struct matches_<Expr, proto::if_<If> > : when<_, If>::template result<void(Expr, int, int)>::type {}; // handle proto::not_ template<typename Expr, typename Grammar> struct matches_<Expr, not_<Grammar> > : mpl::not_<matches_<Expr, typename Grammar::proto_base_expr> > {}; // handle proto::switch_ template<typename Expr, typename Cases> struct matches_<Expr, switch_<Cases> > : matches_< Expr , typename Cases::template case_<typename Expr::proto_tag>::proto_base_expr > {}; } namespace result_of { /// \brief A Boolean metafunction that evaluates whether a given /// expression type matches a grammar. /// /// <tt>matches\<Expr,Grammar\></tt> inherits (indirectly) from /// \c mpl::true_ if <tt>Expr::proto_base_expr</tt> matches /// <tt>Grammar::proto_base_expr</tt>, and from \c mpl::false_ /// otherwise. /// /// Non-terminal expressions are matched against a grammar /// according to the following rules: /// /// \li The wildcard pattern, \c _, matches any expression. /// \li An expression <tt>expr\<AT, argsN\<A0,A1,...An\> \></tt> /// matches a grammar <tt>expr\<BT, argsN\<B0,B1,...Bn\> \></tt> /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx for /// each \c x in <tt>[0,n)</tt>. /// \li An expression <tt>expr\<AT, argsN\<A0,...An,U0,...Um\> \></tt> /// matches a grammar <tt>expr\<BT, argsM\<B0,...Bn,vararg\<V\> \> \></tt> /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx /// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V /// for each \c x in <tt>[0,m)</tt>. /// \li An expression \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E /// matches some \c Bx for \c x in <tt>[0,n)</tt>. /// \li An expression \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E /// matches all \c Bx for \c x in <tt>[0,n)</tt>. /// \li An expression \c E matches <tt>if_\<T,U,V\></tt> if /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt> /// is \c true and \c E matches \c U; or, if /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt> /// is \c false and \c E matches \c V. (Note: \c U defaults to \c _ /// and \c V defaults to \c not_\<_\>.) /// \li An expression \c E matches <tt>not_\<T\></tt> if \c E does /// not match \c T. /// \li An expression \c E matches <tt>switch_\<C\></tt> if /// \c E matches <tt>C::case_\<E::proto_tag\></tt>. /// /// A terminal expression <tt>expr\<tag::terminal,args0\<A\> \></tt> matches /// a grammar <tt>expr\<BT,args0\<B\> \></tt> if \c BT is \c _ or /// \c tag::terminal and one of the following is true: /// /// \li \c B is the wildcard pattern, \c _ /// \li \c A is \c B /// \li \c A is <tt>B &</tt> /// \li \c A is <tt>B const &</tt> /// \li \c B is <tt>exact\<A\></tt> /// \li \c B is <tt>convertible_to\<X\></tt> and /// <tt>is_convertible\<A,X\>::::value</tt> is \c true. /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and /// \c B is <tt>X[proto::N]</tt>. /// \li \c A is <tt>X(&)[M]</tt> and \c B is <tt>X(&)[proto::N]</tt>. /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and /// \c B is <tt>X*</tt>. /// \li \c B lambda-matches \c A (see below). /// /// A type \c B lambda-matches \c A if one of the following is true: /// /// \li \c B is \c A /// \li \c B is the wildcard pattern, \c _ /// \li \c B is <tt>T\<B0,B1,...Bn\></tt> and \c A is /// <tt>T\<A0,A1,...An\></tt> and for each \c x in /// <tt>[0,n)</tt>, \c Ax and \c Bx are types /// such that \c Ax lambda-matches \c Bx template<typename Expr, typename Grammar> struct matches : detail::matches_< typename Expr::proto_base_expr , typename Grammar::proto_base_expr > {}; } namespace wildcardns_ { /// \brief A wildcard grammar element that matches any expression, /// and a transform that returns the current expression unchanged. /// /// The wildcard type, \c _, is a grammar element such that /// <tt>matches\<E,_\>::::value</tt> is \c true for any expression /// type \c E. /// /// The wildcard can also be used as a stand-in for a template /// argument when matching terminals. For instance, the following /// is a grammar that will match any <tt>std::complex\<\></tt> /// terminal: /// /// \code /// BOOST_MPL_ASSERT(( /// matches< /// terminal<std::complex<double> >::type /// , terminal<std::complex< _ > > /// > /// )); /// \endcode /// /// When used as a transform, \c _ returns the current expression /// unchanged. For instance, in the following, \c _ is used with /// the \c fold\<\> transform to fold the children of a node: /// /// \code /// struct CountChildren /// : or_< /// // Terminals have no children /// when<terminal<_>, mpl::int_<0>()> /// // Use fold<> to count the children of non-terminals /// , otherwise< /// fold< /// _ // <-- fold the current expression /// , mpl::int_<0>() /// , mpl::plus<_state, mpl::int_<1> >() /// > /// > /// > /// {}; /// \endcode struct _ : proto::callable { typedef _ proto_base_expr; template<typename Sig> struct result; template<typename This, typename Expr, typename State, typename Visitor> struct result<This(Expr, State, Visitor)> { typedef Expr type; }; /// \param expr An expression /// \return \c expr template<typename Expr, typename State, typename Visitor> Expr const &operator ()(Expr const &expr, State const &, Visitor &) const { return expr; } }; } namespace control { /// \brief Inverts the set of expressions matched by a grammar. When /// used as a transform, \c not_\<\> returns the current expression /// unchanged. /// /// If an expression type \c E does not match a grammar \c G, then /// \c E \e does match <tt>not_\<G\></tt>. For example, /// <tt>not_\<terminal\<_\> \></tt> will match any non-terminal. template<typename Grammar> struct not_ : proto::callable { typedef not_ proto_base_expr; template<typename Sig> struct result; template<typename This, typename Expr, typename State, typename Visitor> struct result<This(Expr, State, Visitor)> { typedef Expr type; }; /// \param expr An expression /// \pre <tt>matches\<Expr,not_\>::::value</tt> is \c true. /// \return \c expr template<typename Expr, typename State, typename Visitor> Expr const &operator ()(Expr const &expr, State const &, Visitor &) const { return expr; } }; /// \brief Used to select one grammar or another based on the result /// of a compile-time Boolean. When used as a transform, \c if_\<\> /// selects between two transforms based on a compile-time Boolean. /// /// When <tt>if_\<If,Then,Else\></tt> is used as a grammar, \c If /// must be a Proto transform and \c Then and \c Else must be grammars. /// An expression type \c E matches <tt>if_\<If,Then,Else\></tt> if /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt> /// is \c true and \c E matches \c U; or, if /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt> /// is \c false and \c E matches \c V. /// /// The template parameter \c Then defaults to \c _ /// and \c Else defaults to \c not\<_\>, so an expression type \c E /// will match <tt>if_\<If\></tt> if and only if /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt> /// is \c true. /// /// \code /// // A grammar that only matches integral terminals, /// // using is_integral<> from Boost.Type_traits. /// struct IsIntegral /// : and_< /// terminal<_> /// , if_< is_integral<_arg>() > /// > /// {}; /// \endcode /// /// When <tt>if_\<If,Then,Else\></tt> is used as a transform, \c If, /// \c Then and \c Else must be Proto transforms. When applying /// the transform to an expression \c E, state \c S and visitor \c V, /// if <tt>when\<_,If\>::::result\<void(E,S,V)\>::::type::value</tt> /// is \c true then the \c Then transform is applied; otherwise /// the \c Else transform is applied. /// /// \code /// // Match a terminal. If the terminal is integral, return /// // mpl::true_; otherwise, return mpl::false_. /// struct IsIntegral2 /// : when< /// terminal<_> /// , if_< /// is_integral<_arg>() /// , mpl::true_() /// , mpl::false_() /// > /// > /// {}; /// \endcode template< typename If , typename Then BOOST_PROTO_FOR_DOXYGEN_ONLY(= _) , typename Else BOOST_PROTO_FOR_DOXYGEN_ONLY(= not_<_>) > struct if_ : proto::callable { typedef if_ proto_base_expr; template<typename Sig> struct result; template<typename This, typename Expr, typename State, typename Visitor> struct result<This(Expr, State, Visitor)> { typedef typename when<_, If>::template result<void(Expr, State, Visitor)>::type condition; typedef typename mpl::if_< condition , when<_, Then> , when<_, Else> >::type which; typedef typename which::template result<void(Expr, State, Visitor)>::type type; }; /// \param expr An expression /// \param state The current state /// \param visitor A visitor of arbitrary type /// \return <tt>result\<void(Expr, State, Visitor)\>::::which()(expr, state, visitor)</tt> template<typename Expr, typename State, typename Visitor> typename result<void(Expr, State, Visitor)>::type operator ()(Expr const &expr, State const &state, Visitor &visitor) const { typedef typename result<void(Expr, State, Visitor)>::which which; return which()(expr, state, visitor); } }; /// \brief For matching one of a set of alternate grammars. Alternates /// tried in order to avoid ambiguity. When used as a transform, \c or_\<\> /// applies the transform associated with the first grammar that matches
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?