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 2004 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 | #ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER |
---|
19 | # include <iostream> |
---|
20 | #endif |
---|
21 | #include <boost/mpl/bool.hpp> |
---|
22 | #include <boost/xpressive/proto/proto_fwd.hpp> |
---|
23 | #include <boost/xpressive/regex_constants.hpp> |
---|
24 | #include <boost/xpressive/detail/detail_fwd.hpp> |
---|
25 | #include <boost/xpressive/detail/core/regex_impl.hpp> |
---|
26 | |
---|
27 | namespace boost { namespace xpressive |
---|
28 | { |
---|
29 | |
---|
30 | /////////////////////////////////////////////////////////////////////////////// |
---|
31 | // basic_regex |
---|
32 | // |
---|
33 | /// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression. |
---|
34 | template<typename BidiIter> |
---|
35 | struct basic_regex |
---|
36 | { |
---|
37 | typedef BidiIter iterator_type; |
---|
38 | typedef typename iterator_value<BidiIter>::type char_type; |
---|
39 | typedef std::basic_string<char_type> string_type; |
---|
40 | typedef regex_constants::syntax_option_type flag_type; |
---|
41 | |
---|
42 | /// \post regex_id() == 0 |
---|
43 | /// \post mark_count() == 0 |
---|
44 | basic_regex() |
---|
45 | : impl_() |
---|
46 | { |
---|
47 | } |
---|
48 | |
---|
49 | /// \param that The basic_regex object to copy. |
---|
50 | /// \post regex_id() == that.regex_id() |
---|
51 | /// \post mark_count() == that.mark_count() |
---|
52 | basic_regex(basic_regex<BidiIter> const &that) |
---|
53 | : impl_(that.impl_) |
---|
54 | { |
---|
55 | } |
---|
56 | |
---|
57 | /// \param that The basic_regex object to copy. |
---|
58 | /// \post regex_id() == that.regex_id() |
---|
59 | /// \post mark_count() == that.mark_count() |
---|
60 | /// \return *this |
---|
61 | basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that) |
---|
62 | { |
---|
63 | this->impl_ = that.impl_; |
---|
64 | return *this; |
---|
65 | } |
---|
66 | |
---|
67 | /// Construct from a static regular expression. |
---|
68 | /// |
---|
69 | /// \param xpr The static regular expression |
---|
70 | /// \pre Xpr is the type of a static regular expression. |
---|
71 | /// \post regex_id() != 0 |
---|
72 | /// \post mark_count() \>= 0 |
---|
73 | template<typename Xpr> |
---|
74 | basic_regex(Xpr const &xpr) |
---|
75 | : impl_() |
---|
76 | { |
---|
77 | this->operator =(xpr); |
---|
78 | } |
---|
79 | |
---|
80 | /// Construct from a static regular expression. |
---|
81 | /// |
---|
82 | /// \param xpr The static regular expression. |
---|
83 | /// \pre Xpr is the type of a static regular expression. |
---|
84 | /// \post regex_id() != 0 |
---|
85 | /// \post mark_count() \>= 0 |
---|
86 | /// \throw std::bad_alloc on out of memory |
---|
87 | /// \return *this |
---|
88 | template<typename Xpr> |
---|
89 | basic_regex<BidiIter> &operator =(Xpr const &xpr) |
---|
90 | { |
---|
91 | detail::static_compile(xpr, *this->impl_.get()); |
---|
92 | return *this; |
---|
93 | } |
---|
94 | |
---|
95 | /// Returns the count of capturing sub-expressions in this regular expression |
---|
96 | /// |
---|
97 | std::size_t mark_count() const |
---|
98 | { |
---|
99 | return this->impl_ ? this->impl_->mark_count_ : 0; |
---|
100 | } |
---|
101 | |
---|
102 | /// Returns a token which uniquely identifies this regular expression. |
---|
103 | /// |
---|
104 | regex_id_type regex_id() const |
---|
105 | { |
---|
106 | return this->impl_ ? this->impl_->xpr_.get() : 0; |
---|
107 | } |
---|
108 | |
---|
109 | /// Swaps the contents of this basic_regex object with another. |
---|
110 | /// |
---|
111 | /// \param that The other basic_regex object. |
---|
112 | /// \attention This is a shallow swap that does not do reference tracking. If you embed |
---|
113 | /// a basic_regex object by reference in another regular expression and then swap its |
---|
114 | /// contents with another basic_regex object, the change will not be visible to the enclosing |
---|
115 | /// regular expression. It is done this way to ensure that swap() cannot throw. |
---|
116 | /// \throw nothrow |
---|
117 | void swap(basic_regex<BidiIter> &that) // throw() |
---|
118 | { |
---|
119 | this->impl_.swap(that.impl_); |
---|
120 | } |
---|
121 | |
---|
122 | /// Factory method for building a regex object from a string. |
---|
123 | /// Equivalent to regex_compiler\< BidiIter \>().compile(str, flags); |
---|
124 | /// |
---|
125 | /// \param str The std::basic_string containing the regular expression. |
---|
126 | /// \param flags Optional bitmask of type syntax_option_type to control how str is interpreted. |
---|
127 | static basic_regex<BidiIter> compile(string_type const &str, flag_type flags = regex_constants::ECMAScript) |
---|
128 | { |
---|
129 | return regex_compiler<BidiIter>().compile(str, flags); |
---|
130 | } |
---|
131 | |
---|
132 | // for binding actions to this regex when it is nested statically in another regex |
---|
133 | /// INTERNAL ONLY |
---|
134 | template<typename Action> |
---|
135 | proto::binary_op |
---|
136 | < |
---|
137 | proto::unary_op<basic_regex<BidiIter>, proto::noop_tag> |
---|
138 | , proto::unary_op<Action, proto::noop_tag> |
---|
139 | , proto::right_shift_tag |
---|
140 | > const |
---|
141 | operator [](detail::action_matcher<Action> const &action) const |
---|
142 | { |
---|
143 | return proto::noop(*this) >> proto::noop(*static_cast<Action const *>(&action)); |
---|
144 | } |
---|
145 | |
---|
146 | //{{AFX_DEBUG |
---|
147 | #ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER |
---|
148 | // BUGBUG debug only |
---|
149 | /// INTERNAL ONLY |
---|
150 | friend std::ostream &operator <<(std::ostream &sout, basic_regex<BidiIter> const &rex) |
---|
151 | { |
---|
152 | rex.dump_(sout); |
---|
153 | return sout; |
---|
154 | } |
---|
155 | #endif |
---|
156 | //}}AFX_DEBUG |
---|
157 | |
---|
158 | private: |
---|
159 | friend struct detail::core_access<BidiIter>; |
---|
160 | |
---|
161 | // Avoid a common programming mistake. Construction from a string is ambiguous. It could mean |
---|
162 | // sregex rx = sregex::compile(str); // compile the string into a regex |
---|
163 | // or |
---|
164 | // sregex rx = as_xpr(str); // treat the string as a literal |
---|
165 | // Since there is no easy way to disambiguate, disallow it and force users to say what they mean |
---|
166 | /// INTERNAL ONLY |
---|
167 | basic_regex(char_type const *); |
---|
168 | /// INTERNAL ONLY |
---|
169 | basic_regex(string_type const &); |
---|
170 | |
---|
171 | // used from parser, via core_access |
---|
172 | /// INTERNAL ONLY |
---|
173 | explicit basic_regex(detail::regex_impl<BidiIter> const &that) |
---|
174 | : impl_() |
---|
175 | { |
---|
176 | this->impl_.tracking_copy(that); |
---|
177 | } |
---|
178 | |
---|
179 | /// INTERNAL ONLY |
---|
180 | bool match_(detail::state_type<BidiIter> &state) const |
---|
181 | { |
---|
182 | return this->impl_->xpr_->match(state); |
---|
183 | } |
---|
184 | |
---|
185 | // Returns true if this basic_regex object does not contain a valid regular expression. |
---|
186 | /// INTERNAL ONLY |
---|
187 | bool invalid_() const |
---|
188 | { |
---|
189 | return !this->impl_ || !this->impl_->xpr_; |
---|
190 | } |
---|
191 | |
---|
192 | /// INTERNAL ONLY |
---|
193 | void dump_(std::ostream &sout) const; |
---|
194 | |
---|
195 | // the tracking_ptr manages lazy-init, COW, cycle-breaking, and |
---|
196 | // reference/dependency tracking. |
---|
197 | detail::tracking_ptr<detail::regex_impl<BidiIter> > impl_; |
---|
198 | }; |
---|
199 | |
---|
200 | //{{AFX_DEBUG |
---|
201 | #ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER |
---|
202 | /////////////////////////////////////////////////////////////////////////////// |
---|
203 | // dump_ |
---|
204 | /// INTERNAL ONLY |
---|
205 | template<typename BidiIter> |
---|
206 | inline void basic_regex<BidiIter>::dump_(std::ostream &sout) const |
---|
207 | { |
---|
208 | if(!this->impl_) |
---|
209 | { |
---|
210 | sout << "<null> refs={} deps={}"; |
---|
211 | } |
---|
212 | else |
---|
213 | { |
---|
214 | sout << *this->impl_; |
---|
215 | } |
---|
216 | } |
---|
217 | #endif |
---|
218 | //}}AFX_DEBUG |
---|
219 | |
---|
220 | /////////////////////////////////////////////////////////////////////////////// |
---|
221 | // swap |
---|
222 | /// \brief Swaps the contents of two basic_regex objects. |
---|
223 | /// \param left The first basic_regex object. |
---|
224 | /// \param right The second basic_regex object. |
---|
225 | /// \attention This is a shallow swap that does not do reference tracking. |
---|
226 | /// If you embed a basic_regex object by reference in another regular expression |
---|
227 | /// and then swap its contents with another basic_regex object, the change will |
---|
228 | /// not be visible to the enclosing regular expression. It is done this way to |
---|
229 | /// ensure that swap() cannot throw. |
---|
230 | /// \throw nothrow |
---|
231 | template<typename BidiIter> |
---|
232 | inline void swap(basic_regex<BidiIter> &left, basic_regex<BidiIter> &right) // throw() |
---|
233 | { |
---|
234 | left.swap(right); |
---|
235 | } |
---|
236 | |
---|
237 | }} // namespace boost::xpressive |
---|
238 | |
---|
239 | #endif // BOOST_XPRESSIVE_REGEX_HPP_EAN_10_04_2005 |
---|