]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/x3/nonterminal/rule.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / 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 // default parse_rule implementation
24 template <typename ID, typename Attribute, typename Iterator
25 , typename Context, typename ActualAttribute>
26 inline detail::default_parse_rule_result
27 parse_rule(
28 rule<ID, Attribute> /* rule_ */
29 , Iterator& first, Iterator const& last
30 , Context const& context, ActualAttribute& attr)
31 {
32 static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
33 "BOOST_SPIRIT_DEFINE undefined for this rule.");
34 return get<ID>(context).parse(first, last, context, unused, attr);
35 }
36
37 template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
38 struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
39 {
40 typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
41 typedef ID id;
42 typedef RHS rhs_type;
43 typedef rule<ID, Attribute> lhs_type;
44 typedef Attribute attribute_type;
45
46 static bool const has_attribute =
47 !is_same<Attribute, unused_type>::value;
48 static bool const handles_container =
49 traits::is_container<Attribute>::value;
50 static bool const force_attribute =
51 force_attribute_;
52
53 rule_definition(RHS const& rhs, char const* name)
54 : rhs(rhs), name(name) {}
55
56 template <typename Iterator, typename Context, typename Attribute_>
57 bool parse(Iterator& first, Iterator const& last
58 , Context const& context, unused_type, Attribute_& attr) const
59 {
60 return detail::rule_parser<attribute_type, ID>
61 ::call_rule_definition(
62 rhs, name, first, last
63 , context
64 , attr
65 , mpl::bool_<force_attribute>());
66 }
67
68 RHS rhs;
69 char const* name;
70 };
71
72 template <typename ID, typename Attribute, bool force_attribute_>
73 struct rule : parser<rule<ID, Attribute>>
74 {
75 typedef ID id;
76 typedef Attribute attribute_type;
77 static bool const has_attribute =
78 !is_same<Attribute, unused_type>::value;
79 static bool const handles_container =
80 traits::is_container<Attribute>::value;
81 static bool const force_attribute = force_attribute_;
82
83 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
84 rule() : name(typeid(rule).name()) {}
85 #else
86 rule() : name("unnamed") {}
87 #endif
88
89 rule(char const* name)
90 : name(name) {}
91
92 template <typename RHS>
93 rule_definition<
94 ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
95 operator=(RHS const& rhs) const
96 {
97 return { as_parser(rhs), name };
98 }
99
100 template <typename RHS>
101 rule_definition<
102 ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
103 operator%=(RHS const& rhs) const
104 {
105 return { as_parser(rhs), name };
106 }
107
108
109 template <typename Iterator, typename Context, typename Attribute_>
110 bool parse(Iterator& first, Iterator const& last
111 , Context const& context, unused_type, Attribute_& attr) const
112 {
113 return parse_rule(*this, first, last, context, attr);
114 }
115
116 char const* name;
117 };
118
119 namespace traits
120 {
121 template <typename T, typename Enable = void>
122 struct is_rule : mpl::false_ {};
123
124 template <typename ID, typename Attribute>
125 struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
126
127 template <typename ID, typename Attribute, typename RHS, bool force_attribute>
128 struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
129 }
130
131 template <typename T>
132 struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
133 {
134 typedef std::string result_type;
135 std::string operator()(T const& r) const
136 {
137 BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
138 return r.name? r.name : "uninitialized";
139 }
140 };
141
142 #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
143 template <typename Iterator, typename Context, typename Attribute> \
144 bool parse_rule( \
145 rule_type rule_ \
146 , Iterator& first, Iterator const& last \
147 , Context const& context, Attribute& attr); \
148 /***/
149
150 #define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
151 BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
152 /***/
153
154 #define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
155 template <typename Iterator, typename Context, typename Attribute> \
156 inline bool parse_rule( \
157 decltype(rule_name) /* rule_ */ \
158 , Iterator& first, Iterator const& last \
159 , Context const& context, Attribute& attr) \
160 { \
161 using boost::spirit::x3::unused; \
162 static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
163 return def_.parse(first, last, context, unused, attr); \
164 } \
165 /***/
166
167 #define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
168 BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
169 /***/
170
171 #define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
172 template bool parse_rule<Iterator, Context, rule_type::attribute_type>( \
173 rule_type rule_ \
174 , Iterator& first, Iterator const& last \
175 , Context const& context, rule_type::attribute_type& attr); \
176 /***/
177
178
179 }}}
180
181 #endif