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
0003
0004
0005
0006
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
0026
0027
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
0046
0047
0048
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
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
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
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)
0219 , detail::make_cons(
0220 Grammar()(
0221 proto::child_c<1>(expr), state, data)
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
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
0342 , detail::make_cons(
0343 Grammar()(
0344 proto::child_c<1>(expr)
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)
0422 , detail::make_cons(
0423 proto::value(proto::child_c<1>(expr)))
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)
0440 , detail::make_cons(
0441 proto::child_c<1>(expr))
0442 );
0443
0444 return make_component_()(elements, data);
0445 }
0446 };
0447 };
0448 }}}
0449
0450 #endif