/* 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_ //#include #include #include #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{ // transform T to a parameter::parameters nmatched signature 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; }; #ifdef BOOST_HAS_VARIADIC_TMPL template struct signature> { typedef parameter::parameters< typename signature_parameter::type... > type; }; #else template struct signature; #ifndef BOOST_DSL_EXPR_PP template struct signature >{ typedef parameter::parameters< typename signature_parameter::type > type; }; template struct signature >{ typedef parameter::parameters< typename signature_parameter::type, typename signature_parameter::type > type; }; template struct signature >{ typedef parameter::parameters< typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type > type; }; template struct signature >{ typedef parameter::parameters< typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type, typename signature_parameter::type > type; }; #endif #endif // bind to the signature the Args provided #ifdef BOOST_HAS_VARIADIC_TMPL template struct args { typedef typename Signature::template bind::type type; }; #else template struct args; #ifndef BOOST_DSL_EXPR_PP 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; }; template struct args > { typedef typename Signature::template bind::type type; }; #endif #endif /* 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 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; }; }; //BOOST_TT_AUX_TYPE_TRAIT_DEF1(parameter_binding,T,typename parameter_binding_impl::type) #ifdef BOOST_HAS_VARIADIC_TMPL template struct unmatched_signature { typedef parameter::parameters< parameter::optional< parameter::deduced, mpl::not_< mpl::or_...> > > > type; }; #else 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; }; #endif // bind to the unmatched signature the Args provided // template // struct unmatched_args > { // typedef typename UnmatchedSignature::template bind::type type; // }; #ifdef BOOST_HAS_VARIADIC_TMPL template struct unmatched_args { typedef typename Signature::template bind::type type; }; #else template struct unmatched_args; #ifndef BOOST_DSL_EXPR_PP 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 struct unmatched_args > { typedef typename UnmatchedSignature::template bind::type type; }; #endif #endif } } } #ifdef BOOST_DSL_EXPR_PP #include #endif namespace boost { namespace dsl { #ifdef BOOST_HAS_VARIADIC_TMPL template class expr { public: typedef Tag tag; typedef expr base_expr; private: typedef Parameters parameters; typedef count::value arity; typedef parameter::parameters< typename signature_parameter::type... > signature; // typedef typename detail::signature::type signature; typedef typename signature::template bind::type type; // typedef typename detail::args::type args; typedef parameter::parameters< parameter::optional< parameter::deduced, mpl::not_< mpl::or_...> > > > unmatched_signature; // typedef typename detail::unmatched_signature::type unmatched_signature; typedef typename unmatched_signature::template bind::type type; // 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; }; }; #else //BOOST_HAS_VARIADIC_TMPL 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; }; }; #endif //BOOST_HAS_VARIADIC_TMPL } // dsl } // boost #endif // BOOST_DSL_EXPR_HPP_