Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/spirit/home/support/make_component.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*=============================================================================
0002   Copyright (c) 2001-2011 Joel de Guzman
0003   http://spirit.sourceforge.net/
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
0009 #define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
0010 
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014 
0015 #include <boost/spirit/home/support/detail/make_cons.hpp>
0016 #include <boost/spirit/home/support/modify.hpp>
0017 #include <boost/phoenix/core/actor.hpp>
0018 #include <boost/phoenix/core/is_actor.hpp>
0019 #include <boost/proto/tags.hpp>
0020 #include <boost/proto/traits.hpp>
0021 #include <boost/proto/transform.hpp>
0022 
0023 namespace boost { namespace spirit
0024 {
0025     // There is no real "component" class. Each domain is responsible
0026     // for creating its own components. You need to specialize this for
0027     // each component in your domain. Use this as a guide.
0028 
0029     template <typename Domain, typename Tag, typename Enable = void>
0030     struct make_component
0031     {
0032         template <typename Sig>
0033         struct result;
0034 
0035         template <typename This, typename Elements, typename Modifiers>
0036         struct result<This(Elements, Modifiers)>;
0037 
0038         template <typename Elements, typename Modifiers>
0039         typename result<make_component(Elements, Modifiers)>::type
0040         operator()(Elements const& elements, Modifiers const& modifiers) const;
0041     };
0042 
0043     namespace tag
0044     {
0045         // Normally, we use proto tags as-is to distinguish operators.
0046         // The special case is proto::tag::subscript. Spirit uses this
0047         // as either sementic actions or directives. To distinguish between
0048         // the two, we use these special tags below.
0049 
0050         struct directive;
0051         struct action;
0052     }
0053 
0054     template <typename Domain, typename T, typename Enable = void>
0055     struct flatten_tree;
0056 }}
0057 
0058 namespace boost { namespace spirit { namespace detail
0059 {
0060     template <typename Expr, typename State, typename Data, typename Domain>
0061     struct make_terminal_impl
0062       : proto::transform_impl<Expr, State, Data>
0063     {
0064         typedef typename
0065             proto::result_of::value<Expr>::type 
0066         value;
0067 
0068         typedef typename result_of::make_cons<value>::type elements;
0069 
0070         typedef
0071             make_component<Domain, proto::tag::terminal>
0072         make_component_;
0073 
0074         typedef typename
0075             make_component_::template
0076                 result<make_component_(elements, Data)>::type
0077         result_type;
0078 
0079         result_type operator()(
0080             typename make_terminal_impl::expr_param expr
0081           , typename make_terminal_impl::state_param /*state*/
0082           , typename make_terminal_impl::data_param data
0083         ) const
0084         {
0085             return typename make_terminal_impl::make_component_()(
0086                 detail::make_cons(proto::value(expr))
0087               , data
0088             );
0089         }
0090     };
0091 
0092     template <typename Expr, typename State, typename Data, typename Domain>
0093     struct make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
0094       : proto::transform_impl<phoenix::actor<Expr>, State, Data>
0095     {
0096         typedef phoenix::actor<Expr> value;
0097         typedef typename result_of::make_cons<value>::type elements;
0098         typedef make_component<Domain, proto::tag::terminal> make_component_;
0099 
0100         typedef typename
0101             make_component_::template
0102                 result<make_component_(elements, Data)>::type
0103         result_type;
0104 
0105         result_type operator()(
0106             typename make_terminal_impl::expr_param expr
0107           , typename make_terminal_impl::state_param /*state*/
0108           , typename make_terminal_impl::data_param data
0109         ) const
0110         {
0111             return typename make_terminal_impl::make_component_()(
0112                 detail::make_cons(expr)
0113               , data
0114             );
0115         }
0116     };
0117 
0118     template <typename Expr, typename State, typename Data, typename Domain>
0119     struct make_terminal_impl<phoenix::actor<Expr> &, State, Data, Domain>
0120         : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
0121     {};
0122 
0123     template <typename Expr, typename State, typename Data, typename Domain>
0124     struct make_terminal_impl<phoenix::actor<Expr> const &, State, Data, Domain>
0125         : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
0126     {};
0127 
0128     template <typename Domain>
0129     struct make_terminal : proto::transform<make_terminal<Domain> >
0130     {
0131         template<typename Expr, typename State, typename Data>
0132         struct impl : make_terminal_impl<Expr, State, Data, Domain> {};
0133     };
0134 
0135     template <typename Domain, typename Tag, typename Grammar>
0136     struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
0137     {
0138         template<typename Expr, typename State, typename Data>
0139         struct impl : proto::transform_impl<Expr, State, Data>
0140         {
0141             typedef typename
0142                 proto::result_of::child_c<Expr, 0>::type
0143             child;
0144 
0145             typedef typename Grammar::
0146                 template result<Grammar(child, State, Data)>::type
0147             child_component;
0148 
0149             typedef typename
0150                 result_of::make_cons<child_component>::type
0151             elements;
0152 
0153             typedef make_component<Domain, Tag> make_component_;
0154 
0155             typedef typename
0156                 make_component_::template
0157                     result<make_component_(elements, Data)>::type
0158             result_type;
0159 
0160             result_type operator()(
0161                 typename impl::expr_param expr
0162               , typename impl::state_param state
0163               , typename impl::data_param data
0164             ) const
0165             {
0166                 return typename impl::make_component_()(
0167                     detail::make_cons(
0168                         Grammar()(proto::child(expr), state, data))
0169                   , data
0170                 );
0171             }
0172         };
0173     };
0174 
0175     // un-flattened version
0176     template <typename Domain, typename Tag, typename Grammar,
0177         bool flatten = flatten_tree<Domain, Tag>::value>
0178     struct make_binary
0179     {
0180         template<typename Expr, typename State, typename Data>
0181         struct impl : proto::transform_impl<Expr, State, Data>
0182         {
0183             typedef typename Grammar::
0184                 template result<Grammar(
0185                     typename proto::result_of::child_c<Expr, 0>::type
0186                   , State, Data)>::type
0187             lhs_component;
0188 
0189             typedef typename Grammar::
0190                 template result<Grammar(
0191                     typename proto::result_of::child_c<Expr, 1>::type
0192                   , State, Data)>::type
0193             rhs_component;
0194 
0195             typedef typename
0196                 result_of::make_cons<
0197                     lhs_component
0198                   , typename result_of::make_cons<rhs_component>::type
0199                 >::type
0200             elements_type;
0201 
0202             typedef make_component<Domain, Tag> make_component_;
0203 
0204             typedef typename
0205                 make_component_::template
0206                     result<make_component_(elements_type, Data)>::type
0207             result_type;
0208 
0209             result_type operator()(
0210                 typename impl::expr_param expr
0211               , typename impl::state_param state
0212               , typename impl::data_param data
0213             ) const
0214             {
0215                 elements_type elements =
0216                     detail::make_cons(
0217                         Grammar()(
0218                             proto::child_c<0>(expr), state, data)       // LHS
0219                       , detail::make_cons(
0220                             Grammar()(
0221                                 proto::child_c<1>(expr), state, data)   // RHS
0222                         )
0223                     );
0224 
0225                 return make_component_()(elements, data);
0226             }
0227         };
0228     };
0229 
0230     template <typename Grammar>
0231     struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
0232     {
0233         template<typename Expr, typename State, typename Data>
0234         struct impl : proto::transform_impl<Expr, State, Data>
0235         {
0236             typedef typename Grammar::
0237                 template result<Grammar(Expr, State, Data)>::type
0238             lhs;
0239 
0240             typedef typename result_of::make_cons<lhs, State>::type result_type;
0241 
0242             result_type operator()(
0243                 typename impl::expr_param expr
0244               , typename impl::state_param state
0245               , typename impl::data_param data
0246             ) const
0247             {
0248                 return detail::make_cons(Grammar()(expr, state, data), state);
0249             }
0250         };
0251     };
0252 
0253     // Flattened version
0254     template <typename Domain, typename Tag, typename Grammar>
0255     struct make_binary<Domain, Tag, Grammar, true>
0256       : proto::transform<make_binary<Domain, Tag, Grammar> >
0257     {
0258         template<typename Expr, typename State, typename Data>
0259         struct impl : proto::transform_impl<Expr, State, Data>
0260         {
0261             typedef typename
0262                 proto::reverse_fold_tree<
0263                     proto::_
0264                   , proto::make<fusion::nil_>
0265                   , make_binary_helper<Grammar>
0266                 >::template impl<Expr, State, Data>
0267             reverse_fold_tree;
0268 
0269             typedef typename reverse_fold_tree::result_type elements;
0270             typedef make_component<Domain, Tag> make_component_;
0271 
0272             typedef typename
0273                 make_component_::template
0274                     result<make_component_(elements, Data)>::type
0275             result_type;
0276 
0277             result_type operator()(
0278                 typename impl::expr_param expr
0279               , typename impl::state_param state
0280               , typename impl::data_param data
0281             ) const
0282             {
0283                 return make_component_()(
0284                     reverse_fold_tree()(expr, state, data), data);
0285             }
0286         };
0287     };
0288 
0289     template <typename Domain, typename Grammar>
0290     struct make_directive : proto::transform<make_directive<Domain, Grammar> >
0291     {
0292         template<typename Expr, typename State, typename Data>
0293         struct impl : proto::transform_impl<Expr, State, Data>
0294         {
0295             typedef typename
0296                 proto::result_of::child_c<Expr, 0>::type
0297             lhs;
0298 
0299             typedef typename
0300                 proto::result_of::value<lhs>::type
0301             tag_type;
0302 
0303             typedef typename modify<Domain>::
0304                 template result<modify<Domain>(tag_type, Data)>::type
0305             modifier_type;
0306 
0307             typedef typename Grammar::
0308                 template result<Grammar(
0309                     typename proto::result_of::child_c<Expr, 1>::type
0310                   , State
0311                   , modifier_type
0312                 )>::type
0313             rhs_component;
0314 
0315             typedef typename
0316                 result_of::make_cons<
0317                     tag_type
0318                   , typename result_of::make_cons<rhs_component>::type
0319                 >::type
0320             elements_type;
0321 
0322             typedef make_component<Domain, tag::directive> make_component_;
0323 
0324             typedef typename
0325                 make_component_::template
0326                     result<make_component_(elements_type, Data)>::type
0327             result_type;
0328 
0329             result_type operator()(
0330                 typename impl::expr_param expr
0331               , typename impl::state_param state
0332               , typename impl::data_param data
0333             ) const
0334             {
0335                 tag_type tag = proto::value(proto::child_c<0>(expr));
0336                 typename remove_reference<modifier_type>::type
0337                     modifier = modify<Domain>()(tag, data);
0338 
0339                 elements_type elements =
0340                     detail::make_cons(
0341                         tag                                 // LHS
0342                       , detail::make_cons(
0343                             Grammar()(
0344                                 proto::child_c<1>(expr)     // RHS
0345                               , state, modifier)
0346                         )
0347                     );
0348 
0349                 return make_component_()(elements, data);
0350             }
0351         };
0352     };
0353 
0354     template <typename Domain, typename Grammar>
0355     struct make_action : proto::transform<make_action<Domain, Grammar> >
0356     {
0357         template<typename Expr, typename State, typename Data>
0358         struct impl : proto::transform_impl<Expr, State, Data>
0359         {
0360             typedef typename Grammar::
0361                 template result<Grammar(
0362                     typename proto::result_of::child_c<Expr, 0>::type
0363                   , State
0364                   , Data
0365                 )>::type
0366             lhs_component;
0367 
0368             typedef
0369                 typename mpl::eval_if_c<
0370                     phoenix::is_actor<
0371                         typename proto::result_of::child_c<Expr, 1>::type
0372                     >::type::value
0373                   , proto::result_of::child_c<Expr, 1>
0374                   , proto::result_of::value<
0375                         typename proto::result_of::child_c<Expr, 1>::type
0376                     >
0377                 >::type
0378                 rhs_component;
0379 
0380             typedef typename
0381                 result_of::make_cons<
0382                     lhs_component
0383                   , typename result_of::make_cons<rhs_component>::type
0384                 >::type
0385             elements_type;
0386 
0387             typedef make_component<Domain, tag::action> make_component_;
0388 
0389             typedef typename
0390                 make_component_::template
0391                     result<make_component_(elements_type, Data)>::type
0392             result_type;
0393 
0394             result_type operator()(
0395                 typename impl::expr_param expr
0396               , typename impl::state_param state
0397               , typename impl::data_param data
0398             ) const
0399             {
0400                 return
0401                     (*this)(
0402                         expr
0403                       , state
0404                       , data
0405                       , typename phoenix::is_actor<
0406                             typename proto::result_of::child_c<Expr, 1>::type
0407                         >::type()
0408                     );
0409             }
0410             
0411             result_type operator()(
0412                 typename impl::expr_param expr
0413               , typename impl::state_param state
0414               , typename impl::data_param data
0415               , mpl::false_
0416             ) const
0417             {
0418                 elements_type elements =
0419                     detail::make_cons(
0420                         Grammar()(
0421                             proto::child_c<0>(expr), state, data)   // LHS
0422                       , detail::make_cons(
0423                             proto::value(proto::child_c<1>(expr)))  // RHS
0424                     );
0425 
0426                 return make_component_()(elements, data);
0427             }
0428 
0429             result_type operator()(
0430                 typename impl::expr_param expr
0431               , typename impl::state_param state
0432               , typename impl::data_param data
0433               , mpl::true_
0434             ) const
0435             {
0436                 elements_type elements =
0437                     detail::make_cons(
0438                         Grammar()(
0439                             proto::child_c<0>(expr), state, data)   // LHS
0440                       , detail::make_cons(
0441                             proto::child_c<1>(expr))               // RHS
0442                     );
0443 
0444                 return make_component_()(elements, data);
0445             }
0446         };
0447     };
0448 }}}
0449 
0450 #endif