/* Copyright 2008 Vicente J. Botet Escriba * 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) * * See http://www.boost.org/libs/ for library home page. */ #ifndef BOOST_DSL_EXPR_HPP_ #define BOOST_DSL_EXPR_HPP_ #if !defined(BOOST_DSL_EXPR_MAX_SIZE) # define BOOST_DSL_EXPR_MAX_SIZE 5 #endif #if !defined(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) # define BOOST_MPL_LIMIT_METAFUNCTION_ARITY BOOST_DSL_EXPR_MAX_SIZE #elif BOOST_MPL_LIMIT_METAFUNCTION_ARITY < BOOST_DSL_EXPR_MAX_SIZE # define BOOST_MPL_LIMIT_METAFUNCTION_ARITY BOOST_DSL_EXPR_MAX_SIZE #endif #if !defined(BOOST_PARAMETER_MAX_ARITY) # define BOOST_PARAMETER_MAX_ARITY BOOST_DSL_EXPR_MAX_SIZE #elif BOOST_PARAMETER_MAX_ARITY < BOOST_DSL_EXPR_MAX_SIZE # define BOOST_PARAMETER_MAX_ARITY BOOST_DSL_EXPR_MAX_SIZE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace dsl { // optional parameter template struct optional { typedef Tag tag; typedef Pred pred; typedef Default default_t; }; // mandatory/required parameter template struct required { typedef Tag tag; typedef Pred pred; typedef Default default_t; }; namespace detail{ template struct get_default_impl { typedef typename Parameter::default_t type; }; template <> struct get_default_impl { typedef mpl::void_ type; }; template struct get_tag_impl { typedef typename Parameter::tag type; }; BOOST_TT_AUX_TYPE_TRAIT_DEF1(get_tag,T,typename get_tag_impl::type) template struct has_tag : is_same { }; // gets the default type associated to a tag template struct default_t2 { typedef typename mpl::find_if >::type iter; typedef mpl::eval_if >, mpl::identity, get_default_impl::type> > type; }; template struct default_t2 { typedef mpl::void_ type; }; template struct default_t { typedef typename mpl::find_if >::type iter; typedef typename mpl::deref::type::default_t type; }; // transform T to a parameter::parameters type template struct signature_parameter; template struct signature_parameter >{ typedef parameter::optional, Pred> type; }; template struct signature_parameter >{ typedef parameter::required, Pred> type; }; template struct signature; // bind to the signature the Args provided template struct args; /* Used for the detection of unmatched template args in a * dsl instantiations. */ struct unmatched_arg; template struct get_pred_impl { typedef typename Parameter::pred type; }; BOOST_TT_AUX_TYPE_TRAIT_DEF1(get_pred,T,typename get_pred_impl::type) template struct parameter_binding_impl { template struct xx { typedef typename mpl::eval_if< boost::is_same, mpl::identity, parameter::binding< Args, Tag , typename detail::default_t2::type > >::type type; }; }; template struct parameter_binding { template< typename T > struct apply { typedef typename parameter_binding_impl::template xx::type type; }; }; template struct unmatched_signature { typedef typename mpl::transform, mpl::back_inserter< mpl::vector0<> > >::type preds; typedef parameter::parameters< parameter::optional< parameter::deduced, mpl::not_< or_seq > > > type; }; // bind to the unmatched signature the Args provided // template // struct unmatched_args > { // typedef typename UnmatchedSignature::template bind::type type; // }; template struct unmatched_args; } } } // include variadic templates using the preprocesor #include namespace boost { namespace dsl { 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)); // typedef typename mpl::transform >::type tags; public: template struct get{ typedef typename parameter::binding< args, TagP, typename detail::default_t::type >::type type; }; }; } // dsl } // boost #endif // BOOST_DSL_EXPR_HPP_