Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/xpressive/basic_regex.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 /// \file basic_regex.hpp | |
3 /// Contains the definition of the basic_regex\<\> class template and its | |
4 /// associated helper functions. | |
5 // | |
6 // Copyright 2008 Eric Niebler. Distributed under the Boost | |
7 // Software License, Version 1.0. (See accompanying file | |
8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | |
10 #ifndef BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005 | |
11 #define BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005 | |
12 | |
13 // MS compatible compilers support #pragma once | |
14 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
15 # pragma once | |
16 #endif | |
17 | |
18 #include <boost/config.hpp> | |
19 #include <boost/mpl/bool.hpp> | |
20 #include <boost/xpressive/xpressive_fwd.hpp> | |
21 #include <boost/xpressive/regex_constants.hpp> | |
22 #include <boost/xpressive/detail/detail_fwd.hpp> | |
23 #include <boost/xpressive/detail/core/regex_impl.hpp> | |
24 #include <boost/xpressive/detail/core/regex_domain.hpp> | |
25 | |
26 // Doxygen can't handle proto :-( | |
27 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED | |
28 # include <boost/xpressive/detail/static/grammar.hpp> | |
29 # include <boost/proto/extends.hpp> | |
30 #endif | |
31 | |
32 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD | |
33 # include <excpt.h> // for _exception_code() | |
34 # include <malloc.h> // for _resetstkoflw() | |
35 #endif | |
36 | |
37 namespace boost { namespace xpressive | |
38 { | |
39 | |
40 namespace detail | |
41 { | |
42 inline void throw_on_stack_error(bool stack_error) | |
43 { | |
44 BOOST_XPR_ENSURE_(!stack_error, regex_constants::error_stack, "Regex stack space exhausted"); | |
45 } | |
46 } | |
47 | |
48 /////////////////////////////////////////////////////////////////////////////// | |
49 // basic_regex | |
50 // | |
51 /// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression. | |
52 template<typename BidiIter> | |
53 struct basic_regex | |
54 : proto::extends< | |
55 proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0> | |
56 , basic_regex<BidiIter> | |
57 , detail::regex_domain | |
58 > | |
59 { | |
60 private: | |
61 typedef proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0> pimpl_type; | |
62 typedef proto::extends<pimpl_type, basic_regex<BidiIter>, detail::regex_domain> base_type; | |
63 | |
64 public: | |
65 typedef BidiIter iterator_type; | |
66 typedef typename iterator_value<BidiIter>::type char_type; | |
67 // For compatibility with std::basic_regex | |
68 typedef typename iterator_value<BidiIter>::type value_type; | |
69 typedef typename detail::string_type<char_type>::type string_type; | |
70 typedef regex_constants::syntax_option_type flag_type; | |
71 | |
72 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ECMAScript = regex_constants::ECMAScript); | |
73 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, icase = regex_constants::icase_); | |
74 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, nosubs = regex_constants::nosubs); | |
75 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, optimize = regex_constants::optimize); | |
76 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, collate = regex_constants::collate); | |
77 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, single_line = regex_constants::single_line); | |
78 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_null = regex_constants::not_dot_null); | |
79 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_newline = regex_constants::not_dot_newline); | |
80 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ignore_white_space = regex_constants::ignore_white_space); | |
81 | |
82 /// \post regex_id() == 0 | |
83 /// \post mark_count() == 0 | |
84 basic_regex() | |
85 : base_type() | |
86 { | |
87 } | |
88 | |
89 /// \param that The basic_regex object to copy. | |
90 /// \post regex_id() == that.regex_id() | |
91 /// \post mark_count() == that.mark_count() | |
92 basic_regex(basic_regex<BidiIter> const &that) | |
93 : base_type(that) | |
94 { | |
95 } | |
96 | |
97 /// \param that The basic_regex object to copy. | |
98 /// \post regex_id() == that.regex_id() | |
99 /// \post mark_count() == that.mark_count() | |
100 /// \return *this | |
101 basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that) | |
102 { | |
103 proto::value(*this) = proto::value(that); | |
104 return *this; | |
105 } | |
106 | |
107 /// Construct from a static regular expression. | |
108 /// | |
109 /// \param expr The static regular expression | |
110 /// \pre Expr is the type of a static regular expression. | |
111 /// \post regex_id() != 0 | |
112 /// \post mark_count() \>= 0 | |
113 template<typename Expr> | |
114 basic_regex(Expr const &expr) | |
115 : base_type() | |
116 { | |
117 BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type); | |
118 this->compile_(expr, is_valid_regex<Expr, char_type>()); | |
119 } | |
120 | |
121 /// Construct from a static regular expression. | |
122 /// | |
123 /// \param expr The static regular expression. | |
124 /// \pre Expr is the type of a static regular expression. | |
125 /// \post regex_id() != 0 | |
126 /// \post mark_count() \>= 0 | |
127 /// \throw std::bad_alloc on out of memory | |
128 /// \return *this | |
129 template<typename Expr> | |
130 basic_regex<BidiIter> &operator =(Expr const &expr) | |
131 { | |
132 BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type); | |
133 this->compile_(expr, is_valid_regex<Expr, char_type>()); | |
134 return *this; | |
135 } | |
136 | |
137 /// Returns the count of capturing sub-expressions in this regular expression | |
138 /// | |
139 std::size_t mark_count() const | |
140 { | |
141 return proto::value(*this) ? proto::value(*this)->mark_count_ : 0; | |
142 } | |
143 | |
144 /// Returns a token which uniquely identifies this regular expression. | |
145 /// | |
146 regex_id_type regex_id() const | |
147 { | |
148 return proto::value(*this) ? proto::value(*this)->xpr_.get() : 0; | |
149 } | |
150 | |
151 /// Swaps the contents of this basic_regex object with another. | |
152 /// | |
153 /// \param that The other basic_regex object. | |
154 /// \attention This is a shallow swap that does not do reference tracking. | |
155 /// If you embed a basic_regex object by reference in another | |
156 /// regular expression and then swap its contents with another | |
157 /// basic_regex object, the change will not be visible to the | |
158 /// enclosing regular expression. It is done this way to ensure | |
159 /// that swap() cannot throw. | |
160 /// \throw nothrow | |
161 void swap(basic_regex<BidiIter> &that) // throw() | |
162 { | |
163 proto::value(*this).swap(proto::value(that)); | |
164 } | |
165 | |
166 /// Factory method for building a regex object from a range of characters. | |
167 /// Equivalent to regex_compiler\< BidiIter \>().compile(begin, end, flags); | |
168 /// | |
169 /// \param begin The beginning of a range of characters representing the | |
170 /// regular expression to compile. | |
171 /// \param end The end of a range of characters representing the | |
172 /// regular expression to compile. | |
173 /// \param flags Optional bitmask that determines how the pat string is | |
174 /// interpreted. (See syntax_option_type.) | |
175 /// \return A basic_regex object corresponding to the regular expression | |
176 /// represented by the character range. | |
177 /// \pre [begin,end) is a valid range. | |
178 /// \pre The range of characters specified by [begin,end) contains a | |
179 /// valid string-based representation of a regular expression. | |
180 /// \throw regex_error when the range of characters has invalid regular | |
181 /// expression syntax. | |
182 template<typename InputIter> | |
183 static basic_regex<BidiIter> compile(InputIter begin, InputIter end, flag_type flags = regex_constants::ECMAScript) | |
184 { | |
185 return regex_compiler<BidiIter>().compile(begin, end, flags); | |
186 } | |
187 | |
188 /// \overload | |
189 /// | |
190 template<typename InputRange> | |
191 static basic_regex<BidiIter> compile(InputRange const &pat, flag_type flags = regex_constants::ECMAScript) | |
192 { | |
193 return regex_compiler<BidiIter>().compile(pat, flags); | |
194 } | |
195 | |
196 /// \overload | |
197 /// | |
198 static basic_regex<BidiIter> compile(char_type const *begin, flag_type flags = regex_constants::ECMAScript) | |
199 { | |
200 return regex_compiler<BidiIter>().compile(begin, flags); | |
201 } | |
202 | |
203 /// \overload | |
204 /// | |
205 static basic_regex<BidiIter> compile(char_type const *begin, std::size_t len, flag_type flags) | |
206 { | |
207 return regex_compiler<BidiIter>().compile(begin, len, flags); | |
208 } | |
209 | |
210 private: | |
211 friend struct detail::core_access<BidiIter>; | |
212 | |
213 // Avoid a common programming mistake. Construction from a string is | |
214 // ambiguous. It could mean: | |
215 // sregex rx = sregex::compile(str); // compile the string into a regex | |
216 // or | |
217 // sregex rx = as_xpr(str); // treat the string as a literal | |
218 // Since there is no easy way to disambiguate, it is disallowed. You must | |
219 // say what you mean. | |
220 | |
221 /// INTERNAL ONLY | |
222 basic_regex(char_type const *); | |
223 /// INTERNAL ONLY | |
224 basic_regex(string_type const &); | |
225 | |
226 /// INTERNAL ONLY | |
227 bool match_(detail::match_state<BidiIter> &state) const | |
228 { | |
229 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD | |
230 bool success = false, stack_error = false; | |
231 __try | |
232 { | |
233 success = proto::value(*this)->xpr_->match(state); | |
234 } | |
235 __except(_exception_code() == 0xC00000FDUL) | |
236 { | |
237 stack_error = true; | |
238 _resetstkoflw(); | |
239 } | |
240 detail::throw_on_stack_error(stack_error); | |
241 return success; | |
242 #else | |
243 return proto::value(*this)->xpr_->match(state); | |
244 #endif | |
245 } | |
246 | |
247 // Compiles valid static regexes into a state machine. | |
248 /// INTERNAL ONLY | |
249 template<typename Expr> | |
250 void compile_(Expr const &expr, mpl::true_) | |
251 { | |
252 detail::static_compile(expr, proto::value(*this).get()); | |
253 } | |
254 | |
255 // No-op for invalid static regexes. | |
256 /// INTERNAL ONLY | |
257 template<typename Expr> | |
258 void compile_(Expr const &, mpl::false_) | |
259 { | |
260 } | |
261 }; | |
262 | |
263 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION | |
264 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ECMAScript; | |
265 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::icase; | |
266 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::nosubs; | |
267 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::optimize; | |
268 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::collate; | |
269 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::single_line; | |
270 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_null; | |
271 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_newline; | |
272 template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ignore_white_space; | |
273 #endif | |
274 | |
275 /////////////////////////////////////////////////////////////////////////////// | |
276 // swap | |
277 /// \brief Swaps the contents of two basic_regex objects. | |
278 /// \param left The first basic_regex object. | |
279 /// \param right The second basic_regex object. | |
280 /// \attention This is a shallow swap that does not do reference tracking. | |
281 /// If you embed a basic_regex object by reference in another | |
282 /// regular expression and then swap its contents with another | |
283 /// basic_regex object, the change will not be visible to the | |
284 /// enclosing regular expression. It is done this way to ensure | |
285 /// that swap() cannot throw. | |
286 /// \throw nothrow | |
287 template<typename BidiIter> | |
288 inline void swap(basic_regex<BidiIter> &left, basic_regex<BidiIter> &right) // throw() | |
289 { | |
290 left.swap(right); | |
291 } | |
292 | |
293 }} // namespace boost::xpressive | |
294 | |
295 #endif // BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005 |