1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file basic_regex.hpp
3 /// Contains the definition of the basic_regex\<\> class template and its
4 /// associated helper functions.
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)
10 #ifndef BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
11 #define BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
13 // MS compatible compilers support #pragma once
14 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
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>
25 // Doxygen can't handle proto :-(
26 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
27 # include <boost/xpressive/detail/static/grammar.hpp>
28 # include <boost/proto/extends.hpp>
31 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
32 # include <excpt.h> // for _exception_code()
33 # include <malloc.h> // for _resetstkoflw()
36 namespace boost
{ namespace xpressive
41 inline void throw_on_stack_error(bool stack_error
)
43 BOOST_XPR_ENSURE_(!stack_error
, regex_constants::error_stack
, "Regex stack space exhausted");
47 ///////////////////////////////////////////////////////////////////////////////
50 /// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression.
51 template<typename BidiIter
>
54 typename
proto::terminal
<detail::tracking_ptr
<detail::regex_impl
<BidiIter
> > >::type
55 , basic_regex
<BidiIter
>
59 typedef typename
proto::terminal
<detail::tracking_ptr
<detail::regex_impl
<BidiIter
> > >::type pimpl_type
;
60 typedef proto::extends
<pimpl_type
, basic_regex
<BidiIter
> > base_type
;
63 typedef BidiIter iterator_type
;
64 typedef typename iterator_value
<BidiIter
>::type char_type
;
65 // For compatibility with std::basic_regex
66 typedef typename iterator_value
<BidiIter
>::type value_type
;
67 typedef typename
detail::string_type
<char_type
>::type string_type
;
68 typedef regex_constants::syntax_option_type flag_type
;
70 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, ECMAScript
= regex_constants::ECMAScript
);
71 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, icase
= regex_constants::icase_
);
72 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, nosubs
= regex_constants::nosubs
);
73 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, optimize
= regex_constants::optimize
);
74 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, collate
= regex_constants::collate
);
75 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, single_line
= regex_constants::single_line
);
76 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, not_dot_null
= regex_constants::not_dot_null
);
77 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, not_dot_newline
= regex_constants::not_dot_newline
);
78 BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type
, ignore_white_space
= regex_constants::ignore_white_space
);
80 /// \post regex_id() == 0
81 /// \post mark_count() == 0
87 /// \param that The basic_regex object to copy.
88 /// \post regex_id() == that.regex_id()
89 /// \post mark_count() == that.mark_count()
90 basic_regex(basic_regex
<BidiIter
> const &that
)
95 /// \param that The basic_regex object to copy.
96 /// \post regex_id() == that.regex_id()
97 /// \post mark_count() == that.mark_count()
99 basic_regex
<BidiIter
> &operator =(basic_regex
<BidiIter
> const &that
)
101 proto::value(*this) = proto::value(that
);
105 /// Construct from a static regular expression.
107 /// \param expr The static regular expression
108 /// \pre Expr is the type of a static regular expression.
109 /// \post regex_id() != 0
110 /// \post mark_count() \>= 0
111 template<typename Expr
>
112 basic_regex(Expr
const &expr
)
115 BOOST_XPRESSIVE_CHECK_REGEX(Expr
, char_type
);
116 this->compile_(expr
, is_valid_regex
<Expr
, char_type
>());
119 /// Construct from a static regular expression.
121 /// \param expr The static regular expression.
122 /// \pre Expr is the type of a static regular expression.
123 /// \post regex_id() != 0
124 /// \post mark_count() \>= 0
125 /// \throw std::bad_alloc on out of memory
127 template<typename Expr
>
128 basic_regex
<BidiIter
> &operator =(Expr
const &expr
)
130 BOOST_XPRESSIVE_CHECK_REGEX(Expr
, char_type
);
131 this->compile_(expr
, is_valid_regex
<Expr
, char_type
>());
135 /// Returns the count of capturing sub-expressions in this regular expression
137 std::size_t mark_count() const
139 return proto::value(*this) ? proto::value(*this)->mark_count_
: 0;
142 /// Returns a token which uniquely identifies this regular expression.
144 regex_id_type
regex_id() const
146 return proto::value(*this) ? proto::value(*this)->xpr_
.get() : 0;
149 /// Swaps the contents of this basic_regex object with another.
151 /// \param that The other basic_regex object.
152 /// \attention This is a shallow swap that does not do reference tracking.
153 /// If you embed a basic_regex object by reference in another
154 /// regular expression and then swap its contents with another
155 /// basic_regex object, the change will not be visible to the
156 /// enclosing regular expression. It is done this way to ensure
157 /// that swap() cannot throw.
159 void swap(basic_regex
<BidiIter
> &that
) // throw()
161 proto::value(*this).swap(proto::value(that
));
164 /// Factory method for building a regex object from a range of characters.
165 /// Equivalent to regex_compiler\< BidiIter \>().compile(begin, end, flags);
167 /// \param begin The beginning of a range of characters representing the
168 /// regular expression to compile.
169 /// \param end The end of a range of characters representing the
170 /// regular expression to compile.
171 /// \param flags Optional bitmask that determines how the pat string is
172 /// interpreted. (See syntax_option_type.)
173 /// \return A basic_regex object corresponding to the regular expression
174 /// represented by the character range.
175 /// \pre [begin,end) is a valid range.
176 /// \pre The range of characters specified by [begin,end) contains a
177 /// valid string-based representation of a regular expression.
178 /// \throw regex_error when the range of characters has invalid regular
179 /// expression syntax.
180 template<typename InputIter
>
181 static basic_regex
<BidiIter
> compile(InputIter begin
, InputIter end
, flag_type flags
= regex_constants::ECMAScript
)
183 return regex_compiler
<BidiIter
>().compile(begin
, end
, flags
);
188 template<typename InputRange
>
189 static basic_regex
<BidiIter
> compile(InputRange
const &pat
, flag_type flags
= regex_constants::ECMAScript
)
191 return regex_compiler
<BidiIter
>().compile(pat
, flags
);
196 static basic_regex
<BidiIter
> compile(char_type
const *begin
, flag_type flags
= regex_constants::ECMAScript
)
198 return regex_compiler
<BidiIter
>().compile(begin
, flags
);
203 static basic_regex
<BidiIter
> compile(char_type
const *begin
, std::size_t len
, flag_type flags
)
205 return regex_compiler
<BidiIter
>().compile(begin
, len
, flags
);
209 friend struct detail::core_access
<BidiIter
>;
211 // Avoid a common programming mistake. Construction from a string is
212 // ambiguous. It could mean:
213 // sregex rx = sregex::compile(str); // compile the string into a regex
215 // sregex rx = as_xpr(str); // treat the string as a literal
216 // Since there is no easy way to disambiguate, it is disallowed. You must
217 // say what you mean.
220 basic_regex(char_type
const *);
222 basic_regex(string_type
const &);
225 bool match_(detail::match_state
<BidiIter
> &state
) const
227 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
228 bool success
= false, stack_error
= false;
231 success
= proto::value(*this)->xpr_
->match(state
);
233 __except(_exception_code() == 0xC00000FDUL
)
238 detail::throw_on_stack_error(stack_error
);
241 return proto::value(*this)->xpr_
->match(state
);
245 // Compiles valid static regexes into a state machine.
247 template<typename Expr
>
248 void compile_(Expr
const &expr
, mpl::true_
)
250 detail::static_compile(expr
, proto::value(*this).get());
253 // No-op for invalid static regexes.
255 template<typename Expr
>
256 void compile_(Expr
const &, mpl::false_
)
261 void dump_(std::ostream
&sout
) const;
264 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
265 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::ECMAScript
;
266 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::icase
;
267 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::nosubs
;
268 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::optimize
;
269 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::collate
;
270 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::single_line
;
271 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::not_dot_null
;
272 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::not_dot_newline
;
273 template<typename BidiIter
> regex_constants::syntax_option_type
const basic_regex
<BidiIter
>::ignore_white_space
;
276 ///////////////////////////////////////////////////////////////////////////////
278 /// \brief Swaps the contents of two basic_regex objects.
279 /// \param left The first basic_regex object.
280 /// \param right The second basic_regex object.
281 /// \attention This is a shallow swap that does not do reference tracking.
282 /// If you embed a basic_regex object by reference in another
283 /// regular expression and then swap its contents with another
284 /// basic_regex object, the change will not be visible to the
285 /// enclosing regular expression. It is done this way to ensure
286 /// that swap() cannot throw.
288 template<typename BidiIter
>
289 inline void swap(basic_regex
<BidiIter
> &left
, basic_regex
<BidiIter
> &right
) // throw()
294 }} // namespace boost::xpressive
296 #endif // BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005