#ifndef BOOST_DSL_EXPR_HPP_ #define BOOST_DSL_EXPR_HPP_ #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace dsl { template struct optional { typedef Tag tag; typedef Pred pred; typedef Default default_t; }; template struct required { typedef Tag tag; typedef Pred pred; typedef Default default_t; }; namespace detail{ #if 0 template struct has_tag : is_same { }; template struct get_pred_impl { typedef typename Parameter::pred type; }; BOOST_TT_AUX_TYPE_TRAIT_DEF1(get_pred,T,typename get_pred_impl::type) #endif #if 1 // gets the default type associated to a tag template struct default_aux; template struct default_aux, Parameters> { typedef Default type; }; template struct default_aux, Parameters> { typedef Default type; }; template struct default_aux { typedef typename default_aux::type, typename mpl::pop_front::type >::type type; }; template struct default_t { typedef typename default_aux::type, typename mpl::pop_front::type >::type type; }; #else // gets the default type associated to a tag template struct default_t { typedef typename mpl::find_if >::type iter; typedef typename mpl::deref::type type; }; #endif // transform T to a parameter::parameters type template struct signature; template struct signature >{ typedef parameter::optional, Pred> type; }; template struct signature >{ typedef parameter::required, Pred> type; }; template struct signature >{ typedef parameter::parameters< typename signature::type > type; }; template struct signature >{ typedef parameter::parameters< typename signature::type, typename signature::type > type; }; template struct signature >{ typedef parameter::parameters< typename signature::type, typename signature::type, typename signature::type > type; }; // bind to the signature the Args provided // template // struct args; template struct args; template struct args > { typedef typename Signature::template bind::type type; }; template struct args > { typedef typename Signature::template bind::type type; }; template struct args > { typedef typename Signature::template bind::type type; }; /* Used for the detection of unmatched template args in a * dsl instantiations. */ struct unmatched_arg; // transform T to a parameter::parameters nmatched signature template struct unmatched_signature; //template //struct unmatched_signature >{ // typedef Pred type; //}; // //template //struct unmatched_signature >{ // typedef Pred type; //}; template struct unmatched_signature >{ typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< typename Param0::pred > > > > type; }; template struct unmatched_signature >{ typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< typename Param0::pred, typename Param1::pred > > > > type; }; template struct unmatched_signature >{ typedef parameter::parameters< parameter::optional< parameter::deduced< detail::unmatched_arg >, mpl::not_< mpl::or_< typename Param0::pred, typename Param1::pred, typename Param2::pred > > > > type; }; // bind to the unmatched signature the Args provided // template // struct unmatched_args > { // typedef typename UnmatchedSignature::template bind::type type; // }; template struct unmatched_args; template struct unmatched_args > { typedef typename UnmatchedSignature::template bind::type type; }; template struct unmatched_args > { typedef typename UnmatchedSignature::template bind::type type; }; template struct unmatched_args > { typedef typename UnmatchedSignature::template bind::type type; }; } template class expr { public: typedef Tag tag; typedef expr base_expr; private: typedef Parameters parameters; typedef mpl::size arity; typedef typename detail::signature::type signature; typedef typename detail::args::type args; typedef typename detail::unmatched_signature::type unmatched_signature; typedef typename detail::unmatched_args::type unmatched_args; typedef typename parameter::binding< unmatched_args,detail::unmatched_arg, detail::unmatched_arg >::type unmatched_arg_detected; /* You have passed a type in the specification of a expr type that * could not be interpreted as a valid argument. */ BOOST_STATIC_ASSERT(( is_same::value)); public: template struct get{ typedef typename parameter::binding< args, TagP, typename detail::default_t::type >::type type; }; }; namespace detail { template struct matches_ : mpl::false_ {}; template struct matches_ : mpl::true_ {}; template struct matches_< Expr, parameter::void_ > : mpl::true_ {}; template struct matches_< expr >, expr > > : mpl::or_, is_same > {}; template struct matches_< expr >, expr > > : mpl::and_< mpl::or_, is_same >, mpl::or_, is_same > > {}; } template struct matches : detail::matches_< typename Expr::base_expr , typename Grammar::base_expr > {}; } // dsl } // boost #endif // BOOST_DSL_EXPR_HPP_