/////////////////////////////////////////////////////////////////////////////// /// \file op_base.hpp /// Contains definitions of unary_op\<\>, binary_op\<\> and nary_op\<\>, /// as well as the is_op\<\> and the make_op() helper function. // // Copyright 2004 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_OP_BASE_HPP_EAN_04_01_2005 #define BOOST_PROTO_OP_BASE_HPP_EAN_04_01_2005 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace proto { /////////////////////////////////////////////////////////////////////////////// // op_root struct op_root { }; /////////////////////////////////////////////////////////////////////////////// // is_proxy template struct is_proxy : mpl::false_ { }; template struct is_proxy > : mpl::true_ { }; /////////////////////////////////////////////////////////////////////////////// // is_op template struct is_op : mpl::or_, is_base_and_derived > { }; /////////////////////////////////////////////////////////////////////////////// // as_op template struct as_op { typedef typename Op::type type; static typename Op::const_reference make(Op const &op) { return op.cast(); } }; template struct as_op { typedef unary_op type; static type const make(T const &t) { return noop(t); } }; // These operators must be members. #define BOOST_PROTO_DEFINE_MEMBER_OPS() \ template \ binary_op::type, assign_tag> const \ operator =(Arg const &arg) const \ { \ return make_op(this->cast(), as_op::make(arg)); \ } \ template \ binary_op::type, subscript_tag> const \ operator [](Arg const &arg) const \ { \ return make_op(this->cast(), as_op::make(arg)); \ } \ nary_op operator ()() const \ { \ return nary_op(this->cast()); \ } \ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PROTO_FUN_OP, _) #define BOOST_PROTO_FUN_OP(z, n, _) \ template \ nary_op \ operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, A, const &a)) const \ { \ return nary_op \ (this->cast() BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a)); \ } /////////////////////////////////////////////////////////////////////////////// // op_base template struct op_base : op_root { typedef Op type; typedef type const &const_reference; Op &cast() { return *static_cast(this); } Op const &cast() const { return *static_cast(this); } BOOST_PROTO_DEFINE_MEMBER_OPS() }; /////////////////////////////////////////////////////////////////////////////// // unary_op template struct unary_op : op_base > { typedef typename value_type::type arg_type; typedef Tag tag_type; arg_type arg; unary_op() : arg() {} explicit unary_op(typename call_traits::param_type arg_) : arg(arg_) {} using op_base >::operator =; }; /////////////////////////////////////////////////////////////////////////////// // binary_op template struct binary_op : op_base > { typedef typename value_type::type left_type; typedef typename value_type::type right_type; typedef Tag tag_type; left_type left; right_type right; binary_op() : left() , right() {} binary_op( typename call_traits::param_type left_ , typename call_traits::param_type right_) : left(left_) , right(right_) {} using op_base >::operator =; }; /////////////////////////////////////////////////////////////////////////////// // nary_op template struct nary_op : op_base > { typedef function_tag tag_type; typedef Fun functor_type; typedef fusion::tuple< BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY, typename value_type::type BOOST_PP_INTERCEPT) > args_type; functor_type functor; args_type args; nary_op() : functor() , args() {} #define BOOST_PROTO_NARY_OP_CTOR(z, n, _) \ nary_op( \ typename call_traits::param_type fun \ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, typename call_traits::param_type a))\ : functor(fun) \ , args(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \ {} BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PROTO_NARY_OP_CTOR, _) #undef BOOST_PROTO_NARY_OP_CTOR using op_base >::operator =; }; /////////////////////////////////////////////////////////////////////////////// // op_proxy template struct op_proxy { typedef Op type; typedef type const const_reference; Param param_; Op const cast() const { return Op(this->param_); } operator Op const() const { return this->cast(); } BOOST_PROTO_DEFINE_MEMBER_OPS() }; template struct op_proxy { typedef Op type; typedef type const const_reference; Op const cast() const { return Op(); } operator Op const() const { return this->cast(); } BOOST_PROTO_DEFINE_MEMBER_OPS() }; /////////////////////////////////////////////////////////////////////////////// // make_op template unary_op const make_op(Arg const &arg) { return unary_op(arg); } /////////////////////////////////////////////////////////////////////////////// // make_op template binary_op const make_op(Left const &left, Right const &right) { return binary_op(left, right); } }} #endif