/////////////////////////////////////////////////////////////////////////////// /// \file default.hpp /// Contains definition of the _default transform, which gives operators their /// usual C++ meanings and uses Boost.Typeof to deduce return types. // // 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_DEFAULT_HPP_EAN_04_04_2008 #define BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace proto { namespace detail { template struct default_case : not_<_> {}; template struct default_case : when, _value> {}; template struct default_cases { template struct case_ : default_case {}; }; #define BOOST_PROTO_UNARY_DEFAULT_EVAL(OP, TAG, MAKE) \ template \ struct BOOST_PP_CAT(default_, TAG) \ : transform > \ { \ template \ struct impl \ : transform_impl \ { \ private: \ typedef typename result_of::child_c::type e0; \ typedef typename Grammar::template impl::result_type r0; \ public: \ BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE(), result_type) \ result_type operator ()( \ typename impl::expr_param e \ , typename impl::state_param s \ , typename impl::data_param d \ ) const \ { \ typename Grammar::template impl t0; \ return OP t0(proto::child_c<0>(e), s, d); \ } \ }; \ }; \ \ template \ struct default_case \ : when, BOOST_PP_CAT(default_, TAG) > \ {}; \ /**/ #define BOOST_PROTO_BINARY_DEFAULT_EVAL(OP, TAG, LMAKE, RMAKE) \ template \ struct BOOST_PP_CAT(default_, TAG) \ : transform > \ { \ template \ struct impl \ : transform_impl \ { \ private: \ typedef typename result_of::child_c::type e0; \ typedef typename result_of::child_c::type e1; \ typedef typename Grammar::template impl::result_type r0; \ typedef typename Grammar::template impl::result_type r1; \ public: \ BOOST_PROTO_DECLTYPE_( \ proto::detail::LMAKE() OP proto::detail::RMAKE() \ , result_type \ ) \ result_type operator ()( \ typename impl::expr_param e \ , typename impl::state_param s \ , typename impl::data_param d \ ) const \ { \ typename Grammar::template impl t0; \ typename Grammar::template impl t1; \ return t0(proto::child_c<0>(e), s, d) \ OP t1(proto::child_c<1>(e), s, d); \ } \ }; \ }; \ \ template \ struct default_case \ : when, BOOST_PP_CAT(default_, TAG) > \ {}; \ /**/ BOOST_PROTO_UNARY_DEFAULT_EVAL(+, unary_plus, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(-, negate, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(*, dereference, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(~, complement, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(&, address_of, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(!, logical_not, make) BOOST_PROTO_UNARY_DEFAULT_EVAL(++, pre_inc, make_mutable) BOOST_PROTO_UNARY_DEFAULT_EVAL(--, pre_dec, make_mutable) BOOST_PROTO_BINARY_DEFAULT_EVAL(<<, shift_left, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(>>, shift_right, make_mutable, make_mutable) BOOST_PROTO_BINARY_DEFAULT_EVAL(*, multiplies, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(/, divides, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(%, modulus, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(+, plus, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(-, minus, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(<, less, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(>, greater, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(<=, less_equal, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(>=, greater_equal, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(==, equal_to, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(!=, not_equal_to, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(||, logical_or, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(&&, logical_and, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(&, bitwise_and, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(|, bitwise_or, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(^, bitwise_xor, make, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(=, assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(<<=, shift_left_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(>>=, shift_right_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(*=, multiplies_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(/=, divides_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(%=, modulus_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(+=, plus_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(-=, minus_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(&=, bitwise_and_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(|=, bitwise_or_assign, make_mutable, make) BOOST_PROTO_BINARY_DEFAULT_EVAL(^=, bitwise_xor_assign, make_mutable, make) #undef BOOST_PROTO_UNARY_DEFAULT_EVAL #undef BOOST_PROTO_BINARY_DEFAULT_EVAL /// INTERNAL ONLY template struct is_member_function_invocation : is_member_function_pointer< typename uncvref< typename Grammar::template impl< typename result_of::child_c::type , State , Data >::result_type >::type > {}; /// INTERNAL ONLY template struct default_mem_ptr_impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename result_of::child_c::type e1; typedef typename Grammar::template impl::result_type r0; typedef typename Grammar::template impl::result_type r1; public: typedef typename detail::mem_ptr_fun::result_type result_type; result_type operator ()( typename default_mem_ptr_impl::expr_param e , typename default_mem_ptr_impl::state_param s , typename default_mem_ptr_impl::data_param d ) const { typename Grammar::template impl t0; typename Grammar::template impl t1; return detail::mem_ptr_fun()( t0(proto::child_c<0>(e), s, d) , t1(proto::child_c<1>(e), s, d) ); } }; /// INTERNAL ONLY template struct default_mem_ptr_impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename result_of::child_c::type e1; typedef typename Grammar::template impl::result_type r0; typedef typename Grammar::template impl::result_type r1; public: typedef detail::memfun result_type; result_type const operator ()( typename default_mem_ptr_impl::expr_param e , typename default_mem_ptr_impl::state_param s , typename default_mem_ptr_impl::data_param d ) const { typename Grammar::template impl t0; typename Grammar::template impl t1; return detail::memfun( t0(proto::child_c<0>(e), s, d) , t1(proto::child_c<1>(e), s, d) ); } }; template struct default_mem_ptr : transform > { template struct impl : default_mem_ptr_impl< Grammar , Expr , State , Data , is_member_function_invocation::value > {}; }; template struct default_case : when, default_mem_ptr > {}; template struct default_post_inc : transform > { template struct impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename Grammar::template impl::result_type r0; public: BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable() ++, result_type) result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { typename Grammar::template impl t0; return t0(proto::child_c<0>(e), s, d) ++; } }; }; template struct default_case : when, default_post_inc > {}; template struct default_post_dec : transform > { template struct impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename Grammar::template impl::result_type r0; public: BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable() --, result_type) result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { typename Grammar::template impl t0; return t0(proto::child_c<0>(e), s, d) --; } }; }; template struct default_case : when, default_post_dec > {}; template struct default_subscript : transform > { template struct impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename result_of::child_c::type e1; typedef typename Grammar::template impl::result_type r0; typedef typename Grammar::template impl::result_type r1; public: BOOST_PROTO_DECLTYPE_( proto::detail::make_subscriptable() [ proto::detail::make() ] , result_type ) result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { typename Grammar::template impl t0; typename Grammar::template impl t1; return t0(proto::child_c<0>(e), s, d) [ t1(proto::child_c<1>(e), s, d) ]; } }; }; template struct default_case : when, default_subscript > {}; template struct default_if_else_ { template struct impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename result_of::child_c::type e1; typedef typename result_of::child_c::type e2; typedef typename Grammar::template impl::result_type r0; typedef typename Grammar::template impl::result_type r1; typedef typename Grammar::template impl::result_type r2; public: BOOST_PROTO_DECLTYPE_( proto::detail::make() ? proto::detail::make() : proto::detail::make() , result_type ) result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { typename Grammar::template impl t0; typename Grammar::template impl t1; typename Grammar::template impl t2; return t0(proto::child_c<0>(e), s, d) ? t1(proto::child_c<1>(e), s, d) : t2(proto::child_c<2>(e), s, d); } }; }; template struct default_case : when, default_if_else_ > {}; template struct default_comma : transform > { template struct impl : transform_impl { private: typedef typename result_of::child_c::type e0; typedef typename result_of::child_c::type e1; typedef typename Grammar::template impl::result_type r0; typedef typename Grammar::template impl::result_type r1; public: typedef typename proto::detail::comma_result::type result_type; result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { typename Grammar::template impl t0; typename Grammar::template impl t1; return t0(proto::child_c<0>(e), s, d) , t1(proto::child_c<1>(e), s, d); } }; }; template struct default_case : when, default_comma > {}; template struct default_function_impl; template struct default_function : transform > { template struct impl : default_function_impl< Grammar , Expr , State , Data , transform_impl::expr::proto_arity_c > {}; }; template struct default_case : when >, default_function > {}; #define BOOST_PROTO_DEFAULT_EVAL_TYPE(Z, N, DATA) \ typedef \ typename result_of::child_c::type \ BOOST_PP_CAT(e, N); \ \ typedef \ typename Grammar::template impl::result_type \ BOOST_PP_CAT(r, N); \ /**/ #define BOOST_PROTO_DEFAULT_EVAL(Z, N, DATA) \ typename Grammar::template impl()( \ proto::child_c(DATA), s, d \ ) \ /**/ template struct default_function_impl : transform_impl { BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr) typedef typename proto::detail::result_of_fixup::type function_type; typedef typename BOOST_PROTO_RESULT_OF::type result_type; result_type operator ()( typename default_function_impl::expr_param e , typename default_function_impl::state_param s , typename default_function_impl::data_param d ) const { return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(); } }; template struct default_function_impl : transform_impl { BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr) BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 1, Expr) typedef typename proto::detail::result_of_fixup::type function_type; typedef typename detail::result_of_::type result_type; result_type operator ()( typename default_function_impl::expr_param e , typename default_function_impl::state_param s , typename default_function_impl::data_param d ) const { return this->invoke( e , s , d , is_member_function_pointer() , is_member_object_pointer() ); } private: result_type invoke( typename default_function_impl::expr_param e , typename default_function_impl::state_param s , typename default_function_impl::data_param d , mpl::false_ , mpl::false_ ) const { return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(BOOST_PROTO_DEFAULT_EVAL(~, 1, e)); } result_type invoke( typename default_function_impl::expr_param e , typename default_function_impl::state_param s , typename default_function_impl::data_param d , mpl::true_ , mpl::false_ ) const { BOOST_PROTO_USE_GET_POINTER(); typedef typename detail::class_member_traits::class_type class_type; return ( BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, e))) ->* BOOST_PROTO_DEFAULT_EVAL(~, 0, e) )(); } result_type invoke( typename default_function_impl::expr_param e , typename default_function_impl::state_param s , typename default_function_impl::data_param d , mpl::false_ , mpl::true_ ) const { BOOST_PROTO_USE_GET_POINTER(); typedef typename detail::class_member_traits::class_type class_type; return ( BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, e))) ->* BOOST_PROTO_DEFAULT_EVAL(~, 0, e) ); } }; #include #undef BOOST_PROTO_DEFAULT_EVAL_TYPE #undef BOOST_PROTO_DEFAULT_EVAL } template struct _default : switch_ > {}; template struct is_callable<_default > : mpl::true_ {}; namespace detail { // Loopy indirection that allows proto::_default<> to be // used without specifying a Grammar argument. struct _default : proto::_default<> {}; } }} #endif