/src/contrib/boost/spirit/home/support/make_component.hpp
http://pythonocc.googlecode.com/ · C++ Header · 364 lines · 296 code · 52 blank · 16 comment · 0 complexity · c8894e15238d50a6e1e8e0a513ffb29c MD5 · raw file
- /*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
- http://spirit.sourceforge.net/
- 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)
- =============================================================================*/
- #ifndef BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
- #define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/proto/proto.hpp>
- #include <boost/spirit/home/support/detail/make_cons.hpp>
- #include <boost/spirit/home/support/modify.hpp>
- namespace boost { namespace spirit
- {
- // There is no real "component" class. Each domain is responsible
- // for creating its own components. You need to specialize this for
- // each component in your domain. Use this as a guide.
- template <typename Domain, typename Tag, typename Enable = void>
- struct make_component
- {
- template <typename Sig>
- struct result;
- template <typename This, typename Elements, typename Modifiers>
- struct result<This(Elements, Modifiers)>;
- template <typename Elements, typename Modifiers>
- typename result<make_component(Elements, Modifiers)>::type
- operator()(Elements const& elements, Modifiers const& modifiers) const;
- };
- namespace tag
- {
- // Normally, we use proto tags as-is to distinguish operators.
- // The special case is proto::tag::subscript. Spirit uses this
- // as either sementic actions or directives. To distinguish between
- // the two, we use these special tags below.
- struct directive;
- struct action;
- }
- template <typename Domain, typename T, typename Enable = void>
- struct flatten_tree;
- }}
- namespace boost { namespace spirit { namespace detail
- {
- template <typename Domain>
- struct make_terminal : proto::transform<make_terminal<Domain> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::value<Expr>::type
- value;
- typedef typename result_of::make_cons<value>::type elements;
- typedef
- make_component<Domain, proto::tag::terminal>
- make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param /*state*/
- , typename impl::data_param data
- ) const
- {
- return typename impl::make_component_()(
- detail::make_cons(proto::value(expr))
- , data
- );
- }
- };
- };
- template <typename Domain, typename Tag, typename Grammar>
- struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::child_c<Expr, 0>::type
- child;
- typedef typename Grammar::
- template result<Grammar(child, State, Data)>::type
- child_component;
- typedef typename
- result_of::make_cons<child_component>::type
- elements;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return typename impl::make_component_()(
- detail::make_cons(
- Grammar()(proto::child(expr), state, data))
- , data
- );
- }
- };
- };
- // un-flattened version
- template <typename Domain, typename Tag, typename Grammar,
- bool flatten = flatten_tree<Domain, Tag>::value>
- struct make_binary
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 0>::type
- , State, Data)>::type
- lhs_component;
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 1>::type
- , State, Data)>::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- lhs_component
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- elements_type elements =
- detail::make_cons(
- Grammar()(
- proto::child_c<0>(expr), state, data) // LHS
- , detail::make_cons(
- Grammar()(
- proto::child_c<1>(expr), state, data) // RHS
- )
- );
- return make_component_()(elements, data);
- }
- };
- };
- template <typename Grammar>
- struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(Expr, State, Data)>::type
- lhs;
- typedef typename result_of::make_cons<lhs, State>::type result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return detail::make_cons(Grammar()(expr, state, data), state);
- }
- };
- };
- // Flattened version
- template <typename Domain, typename Tag, typename Grammar>
- struct make_binary<Domain, Tag, Grammar, true>
- : proto::transform<make_binary<Domain, Tag, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::reverse_fold_tree<
- proto::_
- , proto::make<fusion::nil>
- , make_binary_helper<Grammar>
- >::template impl<Expr, State, Data>
- reverse_fold_tree;
- typedef typename reverse_fold_tree::result_type elements;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return make_component_()(
- reverse_fold_tree()(expr, state, data), data);
- }
- };
- };
- template <typename Domain, typename Grammar>
- struct make_directive : proto::transform<make_directive<Domain, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::child_c<Expr, 0>::type
- lhs;
- typedef typename
- proto::result_of::value<lhs>::type
- tag_type;
- typedef typename modify<Domain>::
- template result<modify<Domain>(tag_type, Data)>::type
- modifier_type;
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 1>::type
- , State
- , modifier_type
- )>::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- tag_type
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, tag::directive> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- tag_type tag = proto::value(proto::child_c<0>(expr));
- typename remove_reference<modifier_type>::type
- modifier = modify<Domain>()(tag, data);
- elements_type elements =
- detail::make_cons(
- tag // LHS
- , detail::make_cons(
- Grammar()(
- proto::child_c<1>(expr) // RHS
- , state, modifier)
- )
- );
- return make_component_()(elements, data);
- }
- };
- };
- template <typename Domain, typename Grammar>
- struct make_action : proto::transform<make_action<Domain, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 0>::type
- , State
- , Data
- )>::type
- lhs_component;
- typedef typename
- proto::result_of::value<
- typename proto::result_of::child_c<Expr, 1>::type
- >::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- lhs_component
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, tag::action> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- elements_type elements =
- detail::make_cons(
- Grammar()(
- proto::child_c<0>(expr), state, data) // LHS
- , detail::make_cons(
- proto::value(proto::child_c<1>(expr))) // RHS
- );
- return make_component_()(elements, data);
- }
- };
- };
- }}}
- #endif