📄 operators.hpp
字号:
////////////////////////////////////////////////////////////////////////////////// \file operators.hpp/// Contains all the overloaded operators that make it possible to build/// Proto expression trees. //// 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_OPERATORS_HPP_EAN_04_01_2005#define BOOST_PROTO_OPERATORS_HPP_EAN_04_01_2005#include <boost/xpressive/proto/detail/prefix.hpp>#include <boost/preprocessor/punctuation/comma.hpp>#include <boost/preprocessor/seq/seq.hpp>#include <boost/mpl/or.hpp>#include <boost/mpl/assert.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/xpressive/proto/proto_fwd.hpp>#include <boost/xpressive/proto/tags.hpp>#include <boost/xpressive/proto/expr.hpp>#include <boost/xpressive/proto/generate.hpp>#include <boost/xpressive/proto/make_expr.hpp>#include <boost/xpressive/proto/detail/suffix.hpp>namespace boost { namespace proto{ namespace detail { template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void> struct as_expr_if2 {}; template<typename Tag, typename Left, typename Right> struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void> : generate_if< typename Left::proto_domain , proto::expr< Tag , args2< ref_<Left> , typename Left::proto_domain::template apply<proto::expr<tag::terminal, args0<Right &> > >::type > > > { typedef proto::expr<tag::terminal, args0<Right &> > term_type; typedef proto::expr<Tag, args2<ref_<Left>, typename Left::proto_domain::template apply<term_type>::type> > expr_type; static typename Left::proto_domain::template apply<expr_type>::type make(Left &left, Right &right) { term_type term = {right}; expr_type that = {{left}, Left::proto_domain::make(term)}; return Left::proto_domain::make(that); } }; template<typename Tag, typename Left, typename Right> struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_> : generate_if< typename Right::proto_domain , proto::expr< Tag , args2< typename Right::proto_domain::template apply<proto::expr<tag::terminal, args0<Left &> > >::type , ref_<Right> > > > { typedef proto::expr<tag::terminal, args0<Left &> > term_type; typedef proto::expr<Tag, args2<typename Right::proto_domain::template apply<term_type>::type, ref_<Right> > > expr_type; static typename Right::proto_domain::template apply<expr_type>::type make(Left &left, Right &right) { term_type term = {left}; expr_type that = {Right::proto_domain::make(term), {right}}; return Right::proto_domain::make(that); } }; template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void> struct as_expr_if : as_expr_if2<Tag, Left, Right> {}; template<typename Tag, typename Left, typename Right> struct as_expr_if<Tag, Left, Right, typename Left::proto_is_expr_, typename Right::proto_is_expr_> : generate_if< typename Left::proto_domain , proto::expr<Tag, args2<ref_<Left>, ref_<Right> > > > { typedef proto::expr<Tag, args2<ref_<Left>, ref_<Right> > > expr_type; BOOST_MPL_ASSERT((is_same<typename Left::proto_domain, typename Right::proto_domain>)); static typename Left::proto_domain::template apply<expr_type>::type make(Left &left, Right &right) { expr_type that = {{left}, {right}}; return Left::proto_domain::make(that); } }; template<typename Arg, typename Trait, typename Enable = void> struct arg_weight { BOOST_STATIC_CONSTANT(int, value = 1 + Trait::value); }; template<typename Arg, typename Trait> struct arg_weight<Arg, Trait, typename Arg::proto_is_expr_> { BOOST_STATIC_CONSTANT(int, value = 0); }; template<typename Domain, typename Trait, typename Arg, typename Expr> struct enable_unary : boost::enable_if< boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::proto_grammar> > , Expr > {}; template<typename Trait, typename Arg, typename Expr> struct enable_unary<deduce_domain, Trait, Arg, Expr> : boost::enable_if< boost::mpl::and_< Trait , boost::proto::matches<Expr, typename domain_of<Arg>::type::proto_grammar> > , Expr > {}; template<typename Trait, typename Arg, typename Expr> struct enable_unary<default_domain, Trait, Arg, Expr> : boost::enable_if<Trait, Expr> {}; template<typename Domain, typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr> struct enable_binary : boost::enable_if< boost::mpl::and_< mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))> , boost::proto::matches<Expr, typename Domain::proto_grammar> > , Expr > {}; template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr> struct enable_binary<deduce_domain, Trait1, Arg1, Trait2, Arg2, Expr> : boost::enable_if< boost::mpl::and_< mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))> , boost::proto::matches<Expr, typename deduce_domain_<typename domain_of<Arg1>::type, Arg2>::type::proto_grammar> > , Expr > {}; template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr> struct enable_binary<default_domain, Trait1, Arg1, Trait2, Arg2, Expr> : boost::enable_if_c< (3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value)) , Expr > {}; } // detail#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST) \ template<typename Arg> \ typename detail::generate_if< \ typename Arg::proto_domain \ , proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > \ >::type const \ operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \ { \ typedef proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > that_type; \ that_type that = {{arg}}; \ return Arg::proto_domain::make(that); \ } \ template<typename Arg> \ typename detail::generate_if< \ typename Arg::proto_domain \ , proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > \ >::type const \ operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \ { \ typedef proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > that_type; \ that_type that = {{arg}}; \ return Arg::proto_domain::make(that); \ } \ /**/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -