]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/xpressive/detail/static/static.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / xpressive / detail / static / static.hpp
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)
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