diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/support/make_component.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/support/make_component.hpp | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/support/make_component.hpp b/3rdParty/Boost/src/boost/spirit/home/support/make_component.hpp new file mode 100644 index 0000000..04a7437 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/support/make_component.hpp @@ -0,0 +1,474 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/spirit/include/phoenix_core.hpp> +#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 Expr, typename State, typename Data, typename Domain> + struct make_terminal_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 make_terminal_impl::expr_param expr + , typename make_terminal_impl::state_param /*state*/ + , typename make_terminal_impl::data_param data + ) const + { + return typename make_terminal_impl::make_component_()( + detail::make_cons(proto::value(expr)) + , data + ); + } + }; + + template <typename Expr, typename State, typename Data, typename Domain> + struct make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain> + : proto::transform_impl<phoenix::actor<Expr>, State, Data> + { + typedef phoenix::actor<Expr> 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 make_terminal_impl::expr_param expr + , typename make_terminal_impl::state_param /*state*/ + , typename make_terminal_impl::data_param data + ) const + { + return typename make_terminal_impl::make_component_()( + detail::make_cons(expr) + , data + ); + } + }; + + template <typename Expr, typename State, typename Data, typename Domain> + struct make_terminal_impl<phoenix::actor<Expr> &, State, Data, Domain> + : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain> + {}; + + template <typename Expr, typename State, typename Data, typename Domain> + struct make_terminal_impl<phoenix::actor<Expr> const &, State, Data, Domain> + : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain> + {}; + + template <typename Domain> + struct make_terminal : proto::transform<make_terminal<Domain> > + { + template<typename Expr, typename State, typename Data> + struct impl : make_terminal_impl<Expr, State, Data, Domain> {}; + }; + + 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; + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + typedef typename + proto::result_of::value< + typename proto::result_of::child_c<Expr, 1>::type + >::type + rhs_component; +#else + typedef + typename mpl::eval_if_c< + phoenix::is_actor< + typename proto::result_of::child_c<Expr, 1>::type + >::type::value + , proto::result_of::child_c<Expr, 1> + , proto::result_of::value< + typename proto::result_of::child_c<Expr, 1>::type + > + >::type + rhs_component; +#endif + + 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; + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + 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); + } +#else + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + ) const + { + return + (*this)( + expr + , state + , data + , typename phoenix::is_actor< + typename proto::result_of::child_c<Expr, 1>::type + >::type() + ); + } + + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + , mpl::false_ + ) 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); + } + + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + , mpl::true_ + ) const + { + elements_type elements = + detail::make_cons( + Grammar()( + proto::child_c<0>(expr), state, data) // LHS + , detail::make_cons( + proto::child_c<1>(expr)) // RHS + ); + + return make_component_()(elements, data); + } +#endif + }; + }; +}}} + +#endif |