Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/xpressive/detail/static/static.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 // static.hpp | |
3 // | |
4 // Copyright 2008 Eric Niebler. Distributed under the Boost | |
5 // Software License, Version 1.0. (See accompanying file | |
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | |
8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005 | |
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005 | |
10 | |
11 // MS compatible compilers support #pragma once | |
12 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
13 # pragma once | |
14 #endif | |
15 | |
16 #include <boost/mpl/assert.hpp> | |
17 #include <boost/xpressive/detail/detail_fwd.hpp> | |
18 #include <boost/xpressive/detail/core/state.hpp> | |
19 #include <boost/xpressive/detail/core/linker.hpp> | |
20 #include <boost/xpressive/detail/core/peeker.hpp> | |
21 #include <boost/xpressive/detail/static/placeholders.hpp> | |
22 #include <boost/xpressive/detail/utility/width.hpp> | |
23 | |
24 // Random thoughts: | |
25 // - must support indirect repeat counts {$n,$m} | |
26 // - add ws to eat whitespace (make *ws illegal) | |
27 // - a{n,m} -> repeat<n,m>(a) | |
28 // - a{$n,$m} -> repeat(n,m)(a) | |
29 // - add nil to match nothing | |
30 // - instead of s1, s2, etc., how about s[1], s[2], etc.? Needlessly verbose? | |
31 | |
32 namespace boost { namespace xpressive { namespace detail | |
33 { | |
34 | |
35 /////////////////////////////////////////////////////////////////////////////// | |
36 // stacked_xpression | |
37 // | |
38 template<typename Top, typename Next> | |
39 struct stacked_xpression | |
40 : Next | |
41 { | |
42 // match | |
43 // delegates to Next | |
44 template<typename BidiIter> | |
45 bool match(match_state<BidiIter> &state) const | |
46 { | |
47 return static_cast<Next const *>(this)-> | |
48 BOOST_NESTED_TEMPLATE push_match<Top>(state); | |
49 } | |
50 | |
51 // top_match | |
52 // jump back to the xpression on top of the xpression stack, | |
53 // and keep the xpression on the stack. | |
54 template<typename BidiIter> | |
55 static bool top_match(match_state<BidiIter> &state, void const *top) | |
56 { | |
57 return static_cast<Top const *>(top)-> | |
58 BOOST_NESTED_TEMPLATE push_match<Top>(state); | |
59 } | |
60 | |
61 // pop_match | |
62 // jump back to the xpression on top of the xpression stack, | |
63 // pop the xpression off the stack. | |
64 template<typename BidiIter> | |
65 static bool pop_match(match_state<BidiIter> &state, void const *top) | |
66 { | |
67 return static_cast<Top const *>(top)->match(state); | |
68 } | |
69 | |
70 // skip_match | |
71 // pop the xpression off the top of the stack and ignore it; call | |
72 // match on next. | |
73 template<typename BidiIter> | |
74 bool skip_match(match_state<BidiIter> &state) const | |
75 { | |
76 // could be static_xpression::skip_impl or stacked_xpression::skip_impl | |
77 // depending on if there is 1 or more than 1 xpression on the | |
78 // xpression stack | |
79 return Top::skip_impl(*static_cast<Next const *>(this), state); | |
80 } | |
81 | |
82 //protected: | |
83 | |
84 // skip_impl | |
85 // implementation of skip_match. | |
86 template<typename That, typename BidiIter> | |
87 static bool skip_impl(That const &that, match_state<BidiIter> &state) | |
88 { | |
89 return that.BOOST_NESTED_TEMPLATE push_match<Top>(state); | |
90 } | |
91 }; | |
92 | |
93 /////////////////////////////////////////////////////////////////////////////// | |
94 // stacked_xpression_cast | |
95 // | |
96 template<typename Top, typename Next> | |
97 inline stacked_xpression<Top, Next> const &stacked_xpression_cast(Next const &next) | |
98 { | |
99 // NOTE: this is a little white lie. The "next" object doesn't really have | |
100 // the type to which we're casting it. It is harmless, though. We are only using | |
101 // the cast to decorate the next object with type information. It is done | |
102 // this way to save stack space. | |
103 BOOST_MPL_ASSERT_RELATION(sizeof(stacked_xpression<Top, Next>), ==, sizeof(Next)); | |
104 return *static_cast<stacked_xpression<Top, Next> const *>(&next); | |
105 } | |
106 | |
107 /////////////////////////////////////////////////////////////////////////////// | |
108 // static_xpression | |
109 // | |
110 template<typename Matcher, typename Next> | |
111 struct static_xpression | |
112 : Matcher | |
113 { | |
114 Next next_; | |
115 | |
116 BOOST_STATIC_CONSTANT(bool, pure = Matcher::pure && Next::pure); | |
117 BOOST_STATIC_CONSTANT( | |
118 std::size_t | |
119 , width = | |
120 Matcher::width != unknown_width::value && Next::width != unknown_width::value | |
121 ? Matcher::width + Next::width | |
122 : unknown_width::value | |
123 ); | |
124 | |
125 static_xpression(Matcher const &matcher = Matcher(), Next const &next = Next()) | |
126 : Matcher(matcher) | |
127 , next_(next) | |
128 { | |
129 } | |
130 | |
131 // match | |
132 // delegates to the Matcher | |
133 template<typename BidiIter> | |
134 bool match(match_state<BidiIter> &state) const | |
135 { | |
136 return this->Matcher::match(state, this->next_); | |
137 } | |
138 | |
139 // push_match | |
140 // call match on this, but also push "Top" onto the xpression | |
141 // stack so we know what we are jumping back to later. | |
142 template<typename Top, typename BidiIter> | |
143 bool push_match(match_state<BidiIter> &state) const | |
144 { | |
145 return this->Matcher::match(state, stacked_xpression_cast<Top>(this->next_)); | |
146 } | |
147 | |
148 // skip_impl | |
149 // implementation of skip_match, called from stacked_xpression::skip_match | |
150 template<typename That, typename BidiIter> | |
151 static bool skip_impl(That const &that, match_state<BidiIter> &state) | |
152 { | |
153 return that.match(state); | |
154 } | |
155 | |
156 // for linking a compiled regular xpression | |
157 template<typename Char> | |
158 void link(xpression_linker<Char> &linker) const | |
159 { | |
160 linker.accept(*static_cast<Matcher const *>(this), &this->next_); | |
161 this->next_.link(linker); | |
162 } | |
163 | |
164 // for building a lead-follow | |
165 template<typename Char> | |
166 void peek(xpression_peeker<Char> &peeker) const | |
167 { | |
168 this->peek_next_(peeker.accept(*static_cast<Matcher const *>(this)), peeker); | |
169 } | |
170 | |
171 // for getting xpression width | |
172 detail::width get_width() const | |
173 { | |
174 return this->get_width_(mpl::size_t<width>()); | |
175 } | |
176 | |
177 private: | |
178 | |
179 static_xpression &operator =(static_xpression const &); | |
180 | |
181 template<typename Char> | |
182 void peek_next_(mpl::true_, xpression_peeker<Char> &peeker) const | |
183 { | |
184 this->next_.peek(peeker); | |
185 } | |
186 | |
187 template<typename Char> | |
188 void peek_next_(mpl::false_, xpression_peeker<Char> &) const | |
189 { | |
190 // no-op | |
191 } | |
192 | |
193 template<std::size_t Width> | |
194 detail::width get_width_(mpl::size_t<Width>) const | |
195 { | |
196 return Width; | |
197 } | |
198 | |
199 detail::width get_width_(unknown_width) const | |
200 { | |
201 // Should only be called in contexts where the width is | |
202 // known to be fixed. | |
203 return this->Matcher::get_width() + this->next_.get_width(); | |
204 } | |
205 }; | |
206 | |
207 /////////////////////////////////////////////////////////////////////////////// | |
208 // make_static | |
209 // | |
210 template<typename Matcher> | |
211 inline static_xpression<Matcher> const | |
212 make_static(Matcher const &matcher) | |
213 { | |
214 return static_xpression<Matcher>(matcher); | |
215 } | |
216 | |
217 template<typename Matcher, typename Next> | |
218 inline static_xpression<Matcher, Next> const | |
219 make_static(Matcher const &matcher, Next const &next) | |
220 { | |
221 return static_xpression<Matcher, Next>(matcher, next); | |
222 } | |
223 | |
224 /////////////////////////////////////////////////////////////////////////////// | |
225 // no_next | |
226 // | |
227 struct no_next | |
228 { | |
229 BOOST_STATIC_CONSTANT(std::size_t, width = 0); | |
230 BOOST_STATIC_CONSTANT(bool, pure = true); | |
231 | |
232 template<typename Char> | |
233 void link(xpression_linker<Char> &) const | |
234 { | |
235 } | |
236 | |
237 template<typename Char> | |
238 void peek(xpression_peeker<Char> &peeker) const | |
239 { | |
240 peeker.fail(); | |
241 } | |
242 | |
243 detail::width get_width() const | |
244 { | |
245 return 0; | |
246 } | |
247 }; | |
248 | |
249 /////////////////////////////////////////////////////////////////////////////// | |
250 // get_mark_number | |
251 // | |
252 inline int get_mark_number(basic_mark_tag const &mark) | |
253 { | |
254 return proto::value(mark).mark_number_; | |
255 } | |
256 | |
257 }}} // namespace boost::xpressive::detail | |
258 | |
259 #endif |