]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / core / non_terminal / impl / subrule.ipp
1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
5
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
12
13 #include <boost/mpl/if.hpp>
14
15 namespace boost { namespace spirit {
16
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
18
19 template <typename FirstT, typename RestT>
20 struct subrule_list;
21
22 template <int ID, typename DefT, typename ContextT>
23 struct subrule_parser;
24
25 namespace impl {
26
27
28 template <int N, typename ListT>
29 struct get_subrule
30 {
31 // First case. ListT is non-empty but the list's
32 // first item does not have the ID we are looking for.
33
34 typedef typename get_subrule<N, typename ListT::rest_t>::type type;
35 };
36
37 template <int ID, typename DefT, typename ContextT, typename RestT>
38 struct get_subrule<
39 ID,
40 subrule_list<
41 subrule_parser<ID, DefT, ContextT>,
42 RestT> >
43 {
44 // Second case. ListT is non-empty and the list's
45 // first item has the ID we are looking for.
46
47 typedef DefT type;
48 };
49
50 template <int ID>
51 struct get_subrule<ID, nil_t>
52 {
53 // Third case. ListT is empty
54 typedef nil_t type;
55 };
56
57
58 template <typename T1, typename T2>
59 struct get_result_t {
60
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.
65
66 typedef typename mpl::if_<
67 boost::is_same<T1, nil_t>, T2, T1
68 >::type type;
69 };
70
71 template <int ID, typename ScannerT, typename ContextResultT>
72 struct get_subrule_result
73 {
74 typedef typename
75 impl::get_subrule<ID, typename ScannerT::list_t>::type
76 parser_t;
77
78 typedef typename parser_result<parser_t, ScannerT>::type
79 def_result_t;
80
81 typedef typename match_result<ScannerT, ContextResultT>::type
82 context_result_t;
83
84 typedef typename get_result_t<context_result_t, def_result_t>::type
85 type;
86 };
87
88 template <typename DefT, typename ScannerT, typename ContextResultT>
89 struct get_subrule_parser_result
90 {
91 typedef typename parser_result<DefT, ScannerT>::type
92 def_result_t;
93
94 typedef typename match_result<ScannerT, ContextResultT>::type
95 context_result_t;
96
97 typedef typename get_result_t<context_result_t, def_result_t>::type
98 type;
99 };
100
101 template <typename SubruleT, int ID>
102 struct same_subrule_id
103 {
104 BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID));
105 };
106
107 template <typename RT, typename ScannerT, int ID>
108 struct parse_subrule
109 {
110 template <typename ListT>
111 static void
112 do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_)
113 {
114 r = list.first.rhs.parse(scan);
115 }
116
117 template <typename ListT>
118 static void
119 do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_)
120 {
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);
124 }
125
126 static void
127 do_(RT& r, ScannerT const& scan)
128 {
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);
132 }
133 };
134
135 }
136
137 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
138
139 }} // namespace boost::spirit::impl
140
141 #endif
142