1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #if !defined(BOOST_SPIRIT_SUBRULE_IPP)
11 #define BOOST_SPIRIT_SUBRULE_IPP
13 #include <boost/mpl/if.hpp>
15 namespace boost { namespace spirit {
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
19 template <typename FirstT, typename RestT>
22 template <int ID, typename DefT, typename ContextT>
23 struct subrule_parser;
28 template <int N, typename ListT>
31 // First case. ListT is non-empty but the list's
32 // first item does not have the ID we are looking for.
34 typedef typename get_subrule<N, typename ListT::rest_t>::type type;
37 template <int ID, typename DefT, typename ContextT, typename RestT>
41 subrule_parser<ID, DefT, ContextT>,
44 // Second case. ListT is non-empty and the list's
45 // first item has the ID we are looking for.
51 struct get_subrule<ID, nil_t>
53 // Third case. ListT is empty
58 template <typename T1, typename T2>
61 // If the result type dictated by the context is nil_t (no closures
62 // present), then the whole subrule_parser return type is equal to
63 // the return type of the right hand side of this subrule_parser,
64 // otherwise it is equal to the dictated return value.
66 typedef typename mpl::if_<
67 boost::is_same<T1, nil_t>, T2, T1
71 template <int ID, typename ScannerT, typename ContextResultT>
72 struct get_subrule_result
75 impl::get_subrule<ID, typename ScannerT::list_t>::type
78 typedef typename parser_result<parser_t, ScannerT>::type
81 typedef typename match_result<ScannerT, ContextResultT>::type
84 typedef typename get_result_t<context_result_t, def_result_t>::type
88 template <typename DefT, typename ScannerT, typename ContextResultT>
89 struct get_subrule_parser_result
91 typedef typename parser_result<DefT, ScannerT>::type
94 typedef typename match_result<ScannerT, ContextResultT>::type
97 typedef typename get_result_t<context_result_t, def_result_t>::type
101 template <typename SubruleT, int ID>
102 struct same_subrule_id
104 BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID));
107 template <typename RT, typename ScannerT, int ID>
110 template <typename ListT>
112 do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_)
114 r = list.first.rhs.parse(scan);
117 template <typename ListT>
119 do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_)
121 typedef typename ListT::rest_t::first_t subrule_t;
122 mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
123 do_parse(r, scan, list.rest, same_id);
127 do_(RT& r, ScannerT const& scan)
129 typedef typename ScannerT::list_t::first_t subrule_t;
130 mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
131 do_parse(r, scan, scan.list, same_id);
137 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
139 }} // namespace boost::spirit::impl