]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/x3/nonterminal/rule.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / x3 / nonterminal / rule.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
8 #define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
9
10 #include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
11 #include <boost/type_traits/is_same.hpp>
12 #include <boost/spirit/home/x3/support/context.hpp>
13 #include <boost/preprocessor/variadic/to_seq.hpp>
14 #include <boost/preprocessor/variadic/elem.hpp>
15 #include <boost/preprocessor/seq/for_each.hpp>
16
17 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
18 #include <typeinfo>
19 #endif
20
21 namespace boost { namespace spirit { namespace x3
22 {
23 template <typename ID>
24 struct identity {};
25
26 // default parse_rule implementation
27 template <typename ID, typename Attribute, typename Iterator
28 , typename Context, typename ActualAttribute>
29 inline detail::default_parse_rule_result
30 parse_rule(
31 rule<ID, Attribute> rule_
32 , Iterator& first, Iterator const& last
33 , Context const& context, ActualAttribute& attr)
34 {
35 static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
36 "BOOST_SPIRIT_DEFINE undefined for this rule.");
37 return get<ID>(context).parse(first, last, context, unused, attr);
38 }
39
40 template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
41 struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
42 {
43 typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
44 typedef ID id;
45 typedef RHS rhs_type;
46 typedef rule<ID, Attribute> lhs_type;
47 typedef Attribute attribute_type;
48
49 static bool const has_attribute =
50 !is_same<Attribute, unused_type>::value;
51 static bool const handles_container =
52 traits::is_container<Attribute>::value;
53 static bool const force_attribute =
54 force_attribute_;
55
56 rule_definition(RHS const& rhs, char const* name)
57 : rhs(rhs), name(name) {}
58
59 template <typename Iterator, typename Context, typename Attribute_>
60 bool parse(Iterator& first, Iterator const& last
61 , Context const& context, unused_type, Attribute_& attr) const
62 {
63 return detail::rule_parser<attribute_type, ID>
64 ::call_rule_definition(
65 rhs, name, first, last
66 , context
67 , attr
68 , mpl::bool_<force_attribute>());
69 }
70
71 RHS rhs;
72 char const* name;
73 };
74
75 template <typename ID, typename Attribute, bool force_attribute_>
76 struct rule : parser<rule<ID, Attribute>>
77 {
78 typedef ID id;
79 typedef Attribute attribute_type;
80 static bool const has_attribute =
81 !is_same<Attribute, unused_type>::value;
82 static bool const handles_container =
83 traits::is_container<Attribute>::value;
84 static bool const force_attribute = force_attribute_;
85
86 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
87 rule() : name(typeid(rule).name()) {}
88 #else
89 rule() : name("unnamed") {}
90 #endif
91
92 rule(char const* name)
93 : name(name) {}
94
95 template <typename RHS>
96 rule_definition<
97 ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
98 operator=(RHS const& rhs) const
99 {
100 return { as_parser(rhs), name };
101 }
102
103 template <typename RHS>
104 rule_definition<
105 ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
106 operator%=(RHS const& rhs) const
107 {
108 return { as_parser(rhs), name };
109 }
110
111
112 template <typename Iterator, typename Context, typename Attribute_>
113 bool parse(Iterator& first, Iterator const& last
114 , Context const& context, unused_type, Attribute_& attr) const
115 {
116 return parse_rule(*this, first, last, context, attr);
117 }
118
119 char const* name;
120 };
121
122 namespace traits
123 {
124 template <typename T, typename Enable = void>
125 struct is_rule : mpl::false_ {};
126
127 template <typename ID, typename Attribute>
128 struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
129
130 template <typename ID, typename Attribute, typename RHS, bool force_attribute>
131 struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
132 }
133
134 template <typename T>
135 struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
136 {
137 typedef std::string result_type;
138 std::string operator()(T const& r) const
139 {
140 return r.name;
141 }
142 };
143
144 #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
145 template <typename Iterator, typename Context, typename Attribute> \
146 bool parse_rule( \
147 rule_type rule_ \
148 , Iterator& first, Iterator const& last \
149 , Context const& context, Attribute& attr); \
150 /***/
151
152 #define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
153 BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
154 /***/
155
156 #define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
157 template <typename Iterator, typename Context, typename Attribute> \
158 inline bool parse_rule( \
159 decltype(rule_name) rule_ \
160 , Iterator& first, Iterator const& last \
161 , Context const& context, Attribute& attr) \
162 { \
163 using boost::spirit::x3::unused; \
164 static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
165 return def_.parse(first, last, context, unused, attr); \
166 } \
167 /***/
168
169 #define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
170 BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
171 /***/
172
173 #define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
174 template bool parse_rule<Iterator, Context, rule_type::attribute_type>( \
175 rule_type rule_ \
176 , Iterator& first, Iterator const& last \
177 , Context const& context, rule_type::attribute_type& attr); \
178 /***/
179
180
181 }}}
182
183 #endif