fix doc example typo
[boost.git] / boost / xpressive / basic_regex.hpp
blob75da069761088bb38251ebc118e1b15a2782f82f
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)
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)
15 # pragma once
16 #endif
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>
29 #endif
31 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
32 # include <excpt.h> // for _exception_code()
33 # include <malloc.h> // for _resetstkoflw()
34 #endif
36 namespace boost { namespace xpressive
39 namespace detail
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 ///////////////////////////////////////////////////////////////////////////////
48 // basic_regex
50 /// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression.
51 template<typename BidiIter>
52 struct basic_regex
53 : proto::extends<
54 typename proto::terminal<detail::tracking_ptr<detail::regex_impl<BidiIter> > >::type
55 , basic_regex<BidiIter>
58 private:
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;
62 public:
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
82 basic_regex()
83 : base_type()
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)
91 : base_type(that)
95 /// \param that The basic_regex object to copy.
96 /// \post regex_id() == that.regex_id()
97 /// \post mark_count() == that.mark_count()
98 /// \return *this
99 basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that)
101 proto::value(*this) = proto::value(that);
102 return *this;
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)
113 : base_type()
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
126 /// \return *this
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>());
132 return *this;
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.
158 /// \throw nothrow
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);
186 /// \overload
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);
194 /// \overload
196 static basic_regex<BidiIter> compile(char_type const *begin, flag_type flags = regex_constants::ECMAScript)
198 return regex_compiler<BidiIter>().compile(begin, flags);
201 /// \overload
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);
208 private:
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
214 // or
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.
219 /// INTERNAL ONLY
220 basic_regex(char_type const *);
221 /// INTERNAL ONLY
222 basic_regex(string_type const &);
224 /// INTERNAL ONLY
225 bool match_(detail::match_state<BidiIter> &state) const
227 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
228 bool success = false, stack_error = false;
229 __try
231 success = proto::value(*this)->xpr_->match(state);
233 __except(_exception_code() == 0xC00000FDUL)
235 stack_error = true;
236 _resetstkoflw();
238 detail::throw_on_stack_error(stack_error);
239 return success;
240 #else
241 return proto::value(*this)->xpr_->match(state);
242 #endif
245 // Compiles valid static regexes into a state machine.
246 /// INTERNAL ONLY
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.
254 /// INTERNAL ONLY
255 template<typename Expr>
256 void compile_(Expr const &, mpl::false_)
260 /// INTERNAL ONLY
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;
274 #endif
276 ///////////////////////////////////////////////////////////////////////////////
277 // swap
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.
287 /// \throw nothrow
288 template<typename BidiIter>
289 inline void swap(basic_regex<BidiIter> &left, basic_regex<BidiIter> &right) // throw()
291 left.swap(right);
294 }} // namespace boost::xpressive
296 #endif // BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005