Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file regex_algorithms.hpp
|
Chris@16
|
3 /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
|
Chris@16
|
10 #define BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
|
Chris@16
|
11
|
Chris@16
|
12 // MS compatible compilers support #pragma once
|
Chris@101
|
13 #if defined(_MSC_VER)
|
Chris@16
|
14 # pragma once
|
Chris@16
|
15 #endif
|
Chris@16
|
16
|
Chris@16
|
17 #include <string>
|
Chris@16
|
18 #include <iterator>
|
Chris@16
|
19 #include <boost/mpl/or.hpp>
|
Chris@16
|
20 #include <boost/range/end.hpp>
|
Chris@16
|
21 #include <boost/range/begin.hpp>
|
Chris@16
|
22 #include <boost/mpl/identity.hpp>
|
Chris@16
|
23 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
24 #include <boost/type_traits/add_const.hpp>
|
Chris@16
|
25 #include <boost/type_traits/is_pointer.hpp>
|
Chris@16
|
26 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
27 #include <boost/xpressive/match_results.hpp>
|
Chris@16
|
28 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
29 #include <boost/xpressive/detail/core/state.hpp>
|
Chris@16
|
30 #include <boost/xpressive/detail/utility/save_restore.hpp>
|
Chris@16
|
31
|
Chris@16
|
32 /// INTERNAL ONLY
|
Chris@16
|
33 ///
|
Chris@16
|
34 #define BOOST_XPR_NONDEDUCED_TYPE_(x) typename mpl::identity<x>::type
|
Chris@16
|
35
|
Chris@16
|
36 namespace boost { namespace xpressive
|
Chris@16
|
37 {
|
Chris@16
|
38
|
Chris@16
|
39 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
40 // regex_match
|
Chris@16
|
41 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
42
|
Chris@16
|
43 namespace detail
|
Chris@16
|
44 {
|
Chris@16
|
45 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
46 // regex_match_impl
|
Chris@16
|
47 template<typename BidiIter>
|
Chris@16
|
48 inline bool regex_match_impl
|
Chris@16
|
49 (
|
Chris@16
|
50 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
51 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
52 , match_results<BidiIter> &what
|
Chris@16
|
53 , basic_regex<BidiIter> const &re
|
Chris@16
|
54 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
55 )
|
Chris@16
|
56 {
|
Chris@16
|
57 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
58 BOOST_ASSERT(0 != re.regex_id());
|
Chris@16
|
59
|
Chris@16
|
60 // the state object holds matching state and
|
Chris@16
|
61 // is passed by reference to all the matchers
|
Chris@16
|
62 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
63 state.flags_.match_all_ = true;
|
Chris@16
|
64 state.sub_match(0).begin_ = begin;
|
Chris@16
|
65
|
Chris@16
|
66 if(access::match(re, state))
|
Chris@16
|
67 {
|
Chris@16
|
68 access::set_prefix_suffix(what, begin, end);
|
Chris@16
|
69 return true;
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 // handle partial matches
|
Chris@16
|
73 else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
|
Chris@16
|
74 {
|
Chris@16
|
75 state.set_partial_match();
|
Chris@16
|
76 return true;
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 access::reset(what);
|
Chris@16
|
80 return false;
|
Chris@16
|
81 }
|
Chris@16
|
82 } // namespace detail
|
Chris@16
|
83
|
Chris@16
|
84 /// \brief See if a regex matches a sequence from beginning to end.
|
Chris@16
|
85 ///
|
Chris@16
|
86 /// Determines whether there is an exact match between the regular expression \c re,
|
Chris@16
|
87 /// and all of the sequence <tt>[begin, end)</tt>.
|
Chris@16
|
88 ///
|
Chris@16
|
89 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
|
Chris@16
|
90 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
|
Chris@16
|
91 /// \param begin The beginning of the sequence.
|
Chris@16
|
92 /// \param end The end of the sequence.
|
Chris@16
|
93 /// \param what The \c match_results struct into which the sub_matches will be written
|
Chris@16
|
94 /// \param re The regular expression object to use
|
Chris@16
|
95 /// \param flags Optional match flags, used to control how the expression is matched
|
Chris@16
|
96 /// against the sequence. (See \c match_flag_type.)
|
Chris@16
|
97 /// \return \c true if a match is found, \c false otherwise
|
Chris@16
|
98 /// \throw regex_error on stack exhaustion
|
Chris@16
|
99 template<typename BidiIter>
|
Chris@16
|
100 inline bool regex_match
|
Chris@16
|
101 (
|
Chris@16
|
102 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
103 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
104 , match_results<BidiIter> &what
|
Chris@16
|
105 , basic_regex<BidiIter> const &re
|
Chris@16
|
106 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
107 )
|
Chris@16
|
108 {
|
Chris@16
|
109 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
110
|
Chris@16
|
111 if(0 == re.regex_id())
|
Chris@16
|
112 {
|
Chris@16
|
113 access::reset(what);
|
Chris@16
|
114 return false;
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
118 }
|
Chris@16
|
119
|
Chris@16
|
120 /// \overload
|
Chris@16
|
121 ///
|
Chris@16
|
122 template<typename BidiIter>
|
Chris@16
|
123 inline bool regex_match
|
Chris@16
|
124 (
|
Chris@16
|
125 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
126 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
127 , basic_regex<BidiIter> const &re
|
Chris@16
|
128 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
129 )
|
Chris@16
|
130 {
|
Chris@16
|
131 if(0 == re.regex_id())
|
Chris@16
|
132 {
|
Chris@16
|
133 return false;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 // BUGBUG this is inefficient
|
Chris@16
|
137 match_results<BidiIter> what;
|
Chris@16
|
138 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 /// \overload
|
Chris@16
|
142 ///
|
Chris@16
|
143 template<typename Char>
|
Chris@16
|
144 inline bool regex_match
|
Chris@16
|
145 (
|
Chris@16
|
146 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
|
Chris@16
|
147 , match_results<Char *> &what
|
Chris@16
|
148 , basic_regex<Char *> const &re
|
Chris@16
|
149 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
150 )
|
Chris@16
|
151 {
|
Chris@16
|
152 typedef detail::core_access<Char *> access;
|
Chris@16
|
153
|
Chris@16
|
154 if(0 == re.regex_id())
|
Chris@16
|
155 {
|
Chris@16
|
156 access::reset(what);
|
Chris@16
|
157 return false;
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 // BUGBUG this is inefficient
|
Chris@16
|
161 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
162 Char *end = begin + std::char_traits<char_type>::length(begin);
|
Chris@16
|
163 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 /// \overload
|
Chris@16
|
167 ///
|
Chris@16
|
168 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
169 inline bool regex_match
|
Chris@16
|
170 (
|
Chris@16
|
171 BidiRange &rng
|
Chris@16
|
172 , match_results<BidiIter> &what
|
Chris@16
|
173 , basic_regex<BidiIter> const &re
|
Chris@16
|
174 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
175 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
176 )
|
Chris@16
|
177 {
|
Chris@16
|
178 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
179
|
Chris@16
|
180 if(0 == re.regex_id())
|
Chris@16
|
181 {
|
Chris@16
|
182 access::reset(what);
|
Chris@16
|
183 return false;
|
Chris@16
|
184 }
|
Chris@16
|
185
|
Chris@16
|
186 // Note that the result iterator of the range must be convertible
|
Chris@16
|
187 // to BidiIter here.
|
Chris@16
|
188 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
189 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
190 }
|
Chris@16
|
191
|
Chris@16
|
192 /// \overload
|
Chris@16
|
193 ///
|
Chris@16
|
194 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
195 inline bool regex_match
|
Chris@16
|
196 (
|
Chris@16
|
197 BidiRange const &rng
|
Chris@16
|
198 , match_results<BidiIter> &what
|
Chris@16
|
199 , basic_regex<BidiIter> const &re
|
Chris@16
|
200 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
201 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
202 )
|
Chris@16
|
203 {
|
Chris@16
|
204 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
205
|
Chris@16
|
206 if(0 == re.regex_id())
|
Chris@16
|
207 {
|
Chris@16
|
208 access::reset(what);
|
Chris@16
|
209 return false;
|
Chris@16
|
210 }
|
Chris@16
|
211
|
Chris@16
|
212 // Note that the result iterator of the range must be convertible
|
Chris@16
|
213 // to BidiIter here.
|
Chris@16
|
214 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
215 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
216 }
|
Chris@16
|
217
|
Chris@16
|
218 /// \overload
|
Chris@16
|
219 ///
|
Chris@16
|
220 template<typename Char>
|
Chris@16
|
221 inline bool regex_match
|
Chris@16
|
222 (
|
Chris@16
|
223 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
|
Chris@16
|
224 , basic_regex<Char *> const &re
|
Chris@16
|
225 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
226 )
|
Chris@16
|
227 {
|
Chris@16
|
228 if(0 == re.regex_id())
|
Chris@16
|
229 {
|
Chris@16
|
230 return false;
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 // BUGBUG this is inefficient
|
Chris@16
|
234 match_results<Char *> what;
|
Chris@16
|
235 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
236 Char *end = begin + std::char_traits<char_type>::length(begin);
|
Chris@16
|
237 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 /// \overload
|
Chris@16
|
241 ///
|
Chris@16
|
242 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
243 inline bool regex_match
|
Chris@16
|
244 (
|
Chris@16
|
245 BidiRange &rng
|
Chris@16
|
246 , basic_regex<BidiIter> const &re
|
Chris@16
|
247 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
248 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
249 )
|
Chris@16
|
250 {
|
Chris@16
|
251 if(0 == re.regex_id())
|
Chris@16
|
252 {
|
Chris@16
|
253 return false;
|
Chris@16
|
254 }
|
Chris@16
|
255
|
Chris@16
|
256 // BUGBUG this is inefficient
|
Chris@16
|
257 match_results<BidiIter> what;
|
Chris@16
|
258 // Note that the result iterator of the range must be convertible
|
Chris@16
|
259 // to BidiIter here.
|
Chris@16
|
260 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
261 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
262 }
|
Chris@16
|
263
|
Chris@16
|
264 /// \overload
|
Chris@16
|
265 ///
|
Chris@16
|
266 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
267 inline bool regex_match
|
Chris@16
|
268 (
|
Chris@16
|
269 BidiRange const &rng
|
Chris@16
|
270 , basic_regex<BidiIter> const &re
|
Chris@16
|
271 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
272 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
273 )
|
Chris@16
|
274 {
|
Chris@16
|
275 if(0 == re.regex_id())
|
Chris@16
|
276 {
|
Chris@16
|
277 return false;
|
Chris@16
|
278 }
|
Chris@16
|
279
|
Chris@16
|
280 // BUGBUG this is inefficient
|
Chris@16
|
281 match_results<BidiIter> what;
|
Chris@16
|
282 // Note that the result iterator of the range must be convertible
|
Chris@16
|
283 // to BidiIter here.
|
Chris@16
|
284 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
285 return detail::regex_match_impl(begin, end, what, re, flags);
|
Chris@16
|
286 }
|
Chris@16
|
287
|
Chris@16
|
288
|
Chris@16
|
289 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
290 // regex_search
|
Chris@16
|
291 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
292
|
Chris@16
|
293 namespace detail
|
Chris@16
|
294 {
|
Chris@16
|
295 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
296 // regex_search_impl
|
Chris@16
|
297 template<typename BidiIter>
|
Chris@16
|
298 inline bool regex_search_impl
|
Chris@16
|
299 (
|
Chris@16
|
300 match_state<BidiIter> &state
|
Chris@16
|
301 , basic_regex<BidiIter> const &re
|
Chris@16
|
302 , bool not_initial_null = false
|
Chris@16
|
303 )
|
Chris@16
|
304 {
|
Chris@16
|
305 typedef core_access<BidiIter> access;
|
Chris@16
|
306 match_results<BidiIter> &what = *state.context_.results_ptr_;
|
Chris@16
|
307 BOOST_ASSERT(0 != re.regex_id());
|
Chris@16
|
308
|
Chris@16
|
309 bool const partial_ok = state.flags_.match_partial_;
|
Chris@16
|
310 save_restore<bool> not_null(state.flags_.match_not_null_, state.flags_.match_not_null_ || not_initial_null);
|
Chris@16
|
311 state.flags_.match_prev_avail_ = state.flags_.match_prev_avail_ || !state.bos();
|
Chris@16
|
312
|
Chris@16
|
313 regex_impl<BidiIter> const &impl = *access::get_regex_impl(re);
|
Chris@16
|
314 BidiIter const begin = state.cur_, end = state.end_;
|
Chris@16
|
315 BidiIter &sub0begin = state.sub_match(0).begin_;
|
Chris@16
|
316 sub0begin = state.cur_;
|
Chris@16
|
317
|
Chris@16
|
318 // If match_continuous is set, we only need to check for a match at the current position
|
Chris@16
|
319 if(state.flags_.match_continuous_)
|
Chris@16
|
320 {
|
Chris@16
|
321 if(access::match(re, state))
|
Chris@16
|
322 {
|
Chris@16
|
323 access::set_prefix_suffix(what, begin, end);
|
Chris@16
|
324 return true;
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327 // handle partial matches
|
Chris@16
|
328 else if(partial_ok && state.found_partial_match_)
|
Chris@16
|
329 {
|
Chris@16
|
330 state.set_partial_match();
|
Chris@16
|
331 return true;
|
Chris@16
|
332 }
|
Chris@16
|
333 }
|
Chris@16
|
334
|
Chris@16
|
335 // If we have a finder, use it to find where a potential match can start
|
Chris@16
|
336 else if(impl.finder_ && (!partial_ok || impl.finder_->ok_for_partial_matches()))
|
Chris@16
|
337 {
|
Chris@16
|
338 finder<BidiIter> const &find = *impl.finder_;
|
Chris@16
|
339 if(find(state))
|
Chris@16
|
340 {
|
Chris@16
|
341 if(state.cur_ != begin)
|
Chris@16
|
342 {
|
Chris@16
|
343 not_null.restore();
|
Chris@16
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 do
|
Chris@16
|
347 {
|
Chris@16
|
348 sub0begin = state.cur_;
|
Chris@16
|
349 if(access::match(re, state))
|
Chris@16
|
350 {
|
Chris@16
|
351 access::set_prefix_suffix(what, begin, end);
|
Chris@16
|
352 return true;
|
Chris@16
|
353 }
|
Chris@16
|
354
|
Chris@16
|
355 // handle partial matches
|
Chris@16
|
356 else if(partial_ok && state.found_partial_match_)
|
Chris@16
|
357 {
|
Chris@16
|
358 state.set_partial_match();
|
Chris@16
|
359 return true;
|
Chris@16
|
360 }
|
Chris@16
|
361
|
Chris@16
|
362 BOOST_ASSERT(state.cur_ == sub0begin);
|
Chris@16
|
363 not_null.restore();
|
Chris@16
|
364 }
|
Chris@16
|
365 while(state.cur_ != state.end_ && (++state.cur_, find(state)));
|
Chris@16
|
366 }
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 // Otherwise, use brute force search at every position.
|
Chris@16
|
370 else
|
Chris@16
|
371 {
|
Chris@16
|
372 for(;;)
|
Chris@16
|
373 {
|
Chris@16
|
374 if(access::match(re, state))
|
Chris@16
|
375 {
|
Chris@16
|
376 access::set_prefix_suffix(what, begin, end);
|
Chris@16
|
377 return true;
|
Chris@16
|
378 }
|
Chris@16
|
379
|
Chris@16
|
380 // handle partial matches
|
Chris@16
|
381 else if(partial_ok && state.found_partial_match_)
|
Chris@16
|
382 {
|
Chris@16
|
383 state.set_partial_match();
|
Chris@16
|
384 return true;
|
Chris@16
|
385 }
|
Chris@16
|
386
|
Chris@16
|
387 else if(end == sub0begin)
|
Chris@16
|
388 {
|
Chris@16
|
389 break;
|
Chris@16
|
390 }
|
Chris@16
|
391
|
Chris@16
|
392 BOOST_ASSERT(state.cur_ == sub0begin);
|
Chris@16
|
393 state.cur_ = ++sub0begin;
|
Chris@16
|
394 not_null.restore();
|
Chris@16
|
395 }
|
Chris@16
|
396 }
|
Chris@16
|
397
|
Chris@16
|
398 access::reset(what);
|
Chris@16
|
399 return false;
|
Chris@16
|
400 }
|
Chris@16
|
401 } // namespace detail
|
Chris@16
|
402
|
Chris@16
|
403
|
Chris@16
|
404 /// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
|
Chris@16
|
405 /// that matches the regular expression \c re.
|
Chris@16
|
406 ///
|
Chris@16
|
407 /// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
|
Chris@16
|
408 /// the regular expression \c re.
|
Chris@16
|
409 ///
|
Chris@16
|
410 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
|
Chris@16
|
411 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
|
Chris@16
|
412 /// \param begin The beginning of the sequence
|
Chris@16
|
413 /// \param end The end of the sequence
|
Chris@16
|
414 /// \param what The \c match_results struct into which the sub_matches will be written
|
Chris@16
|
415 /// \param re The regular expression object to use
|
Chris@16
|
416 /// \param flags Optional match flags, used to control how the expression is matched against
|
Chris@16
|
417 /// the sequence. (See \c match_flag_type.)
|
Chris@16
|
418 /// \return \c true if a match is found, \c false otherwise
|
Chris@16
|
419 /// \throw regex_error on stack exhaustion
|
Chris@16
|
420 template<typename BidiIter>
|
Chris@16
|
421 inline bool regex_search
|
Chris@16
|
422 (
|
Chris@16
|
423 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
424 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
425 , match_results<BidiIter> &what
|
Chris@16
|
426 , basic_regex<BidiIter> const &re
|
Chris@16
|
427 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
428 )
|
Chris@16
|
429 {
|
Chris@16
|
430 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
431
|
Chris@16
|
432 // a default-constructed regex matches nothing
|
Chris@16
|
433 if(0 == re.regex_id())
|
Chris@16
|
434 {
|
Chris@16
|
435 access::reset(what);
|
Chris@16
|
436 return false;
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 // the state object holds matching state and
|
Chris@16
|
440 // is passed by reference to all the matchers
|
Chris@16
|
441 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
442 return detail::regex_search_impl(state, re);
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 /// \overload
|
Chris@16
|
446 ///
|
Chris@16
|
447 template<typename BidiIter>
|
Chris@16
|
448 inline bool regex_search
|
Chris@16
|
449 (
|
Chris@16
|
450 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
451 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
452 , basic_regex<BidiIter> const &re
|
Chris@16
|
453 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
454 )
|
Chris@16
|
455 {
|
Chris@16
|
456 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
457
|
Chris@16
|
458 // a default-constructed regex matches nothing
|
Chris@16
|
459 if(0 == re.regex_id())
|
Chris@16
|
460 {
|
Chris@16
|
461 return false;
|
Chris@16
|
462 }
|
Chris@16
|
463
|
Chris@16
|
464 // BUGBUG this is inefficient
|
Chris@16
|
465 match_results<BidiIter> what;
|
Chris@16
|
466 // the state object holds matching state and
|
Chris@16
|
467 // is passed by reference to all the matchers
|
Chris@16
|
468 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
469 return detail::regex_search_impl(state, re);
|
Chris@16
|
470 }
|
Chris@16
|
471
|
Chris@16
|
472 /// \overload
|
Chris@16
|
473 ///
|
Chris@16
|
474 template<typename Char>
|
Chris@16
|
475 inline bool regex_search
|
Chris@16
|
476 (
|
Chris@16
|
477 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
|
Chris@16
|
478 , match_results<Char *> &what
|
Chris@16
|
479 , basic_regex<Char *> const &re
|
Chris@16
|
480 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
481 )
|
Chris@16
|
482 {
|
Chris@16
|
483 typedef detail::core_access<Char *> access;
|
Chris@16
|
484
|
Chris@16
|
485 // a default-constructed regex matches nothing
|
Chris@16
|
486 if(0 == re.regex_id())
|
Chris@16
|
487 {
|
Chris@16
|
488 access::reset(what);
|
Chris@16
|
489 return false;
|
Chris@16
|
490 }
|
Chris@16
|
491
|
Chris@16
|
492 // BUGBUG this is inefficient
|
Chris@16
|
493 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
494 Char *end = begin + std::char_traits<char_type>::length(begin);
|
Chris@16
|
495 // the state object holds matching state and
|
Chris@16
|
496 // is passed by reference to all the matchers
|
Chris@16
|
497 detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
498 return detail::regex_search_impl(state, re);
|
Chris@16
|
499 }
|
Chris@16
|
500
|
Chris@16
|
501 /// \overload
|
Chris@16
|
502 ///
|
Chris@16
|
503 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
504 inline bool regex_search
|
Chris@16
|
505 (
|
Chris@16
|
506 BidiRange &rng
|
Chris@16
|
507 , match_results<BidiIter> &what
|
Chris@16
|
508 , basic_regex<BidiIter> const &re
|
Chris@16
|
509 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
510 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
511 )
|
Chris@16
|
512 {
|
Chris@16
|
513 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
514
|
Chris@16
|
515 // a default-constructed regex matches nothing
|
Chris@16
|
516 if(0 == re.regex_id())
|
Chris@16
|
517 {
|
Chris@16
|
518 access::reset(what);
|
Chris@16
|
519 return false;
|
Chris@16
|
520 }
|
Chris@16
|
521
|
Chris@16
|
522 // Note that the result iterator of the range must be convertible
|
Chris@16
|
523 // to BidiIter here.
|
Chris@16
|
524 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
525 // the state object holds matching state and
|
Chris@16
|
526 // is passed by reference to all the matchers
|
Chris@16
|
527 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
528 return detail::regex_search_impl(state, re);
|
Chris@16
|
529 }
|
Chris@16
|
530
|
Chris@16
|
531 /// \overload
|
Chris@16
|
532 ///
|
Chris@16
|
533 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
534 inline bool regex_search
|
Chris@16
|
535 (
|
Chris@16
|
536 BidiRange const &rng
|
Chris@16
|
537 , match_results<BidiIter> &what
|
Chris@16
|
538 , basic_regex<BidiIter> const &re
|
Chris@16
|
539 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
540 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
541 )
|
Chris@16
|
542 {
|
Chris@16
|
543 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
544
|
Chris@16
|
545 // a default-constructed regex matches nothing
|
Chris@16
|
546 if(0 == re.regex_id())
|
Chris@16
|
547 {
|
Chris@16
|
548 access::reset(what);
|
Chris@16
|
549 return false;
|
Chris@16
|
550 }
|
Chris@16
|
551
|
Chris@16
|
552 // Note that the result iterator of the range must be convertible
|
Chris@16
|
553 // to BidiIter here.
|
Chris@16
|
554 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
555 // the state object holds matching state and
|
Chris@16
|
556 // is passed by reference to all the matchers
|
Chris@16
|
557 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
558 return detail::regex_search_impl(state, re);
|
Chris@16
|
559 }
|
Chris@16
|
560
|
Chris@16
|
561 /// \overload
|
Chris@16
|
562 ///
|
Chris@16
|
563 template<typename Char>
|
Chris@16
|
564 inline bool regex_search
|
Chris@16
|
565 (
|
Chris@16
|
566 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
|
Chris@16
|
567 , basic_regex<Char *> const &re
|
Chris@16
|
568 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
569 )
|
Chris@16
|
570 {
|
Chris@16
|
571 typedef detail::core_access<Char *> access;
|
Chris@16
|
572
|
Chris@16
|
573 // a default-constructed regex matches nothing
|
Chris@16
|
574 if(0 == re.regex_id())
|
Chris@16
|
575 {
|
Chris@16
|
576 return false;
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 // BUGBUG this is inefficient
|
Chris@16
|
580 match_results<Char *> what;
|
Chris@16
|
581 // BUGBUG this is inefficient
|
Chris@16
|
582 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
583 Char *end = begin + std::char_traits<char_type>::length(begin);
|
Chris@16
|
584 // the state object holds matching state and
|
Chris@16
|
585 // is passed by reference to all the matchers
|
Chris@16
|
586 detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
587 return detail::regex_search_impl(state, re);
|
Chris@16
|
588 }
|
Chris@16
|
589
|
Chris@16
|
590 /// \overload
|
Chris@16
|
591 ///
|
Chris@16
|
592 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
593 inline bool regex_search
|
Chris@16
|
594 (
|
Chris@16
|
595 BidiRange &rng
|
Chris@16
|
596 , basic_regex<BidiIter> const &re
|
Chris@16
|
597 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
598 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
599 )
|
Chris@16
|
600 {
|
Chris@16
|
601 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
602
|
Chris@16
|
603 // a default-constructed regex matches nothing
|
Chris@16
|
604 if(0 == re.regex_id())
|
Chris@16
|
605 {
|
Chris@16
|
606 return false;
|
Chris@16
|
607 }
|
Chris@16
|
608
|
Chris@16
|
609 // BUGBUG this is inefficient
|
Chris@16
|
610 match_results<BidiIter> what;
|
Chris@16
|
611 // Note that the result iterator of the range must be convertible
|
Chris@16
|
612 // to BidiIter here.
|
Chris@16
|
613 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
614 // the state object holds matching state and
|
Chris@16
|
615 // is passed by reference to all the matchers
|
Chris@16
|
616 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
617 return detail::regex_search_impl(state, re);
|
Chris@16
|
618 }
|
Chris@16
|
619
|
Chris@16
|
620 /// \overload
|
Chris@16
|
621 ///
|
Chris@16
|
622 template<typename BidiRange, typename BidiIter>
|
Chris@16
|
623 inline bool regex_search
|
Chris@16
|
624 (
|
Chris@16
|
625 BidiRange const &rng
|
Chris@16
|
626 , basic_regex<BidiIter> const &re
|
Chris@16
|
627 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
628 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
|
Chris@16
|
629 )
|
Chris@16
|
630 {
|
Chris@16
|
631 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
632
|
Chris@16
|
633 // a default-constructed regex matches nothing
|
Chris@16
|
634 if(0 == re.regex_id())
|
Chris@16
|
635 {
|
Chris@16
|
636 return false;
|
Chris@16
|
637 }
|
Chris@16
|
638
|
Chris@16
|
639 // BUGBUG this is inefficient
|
Chris@16
|
640 match_results<BidiIter> what;
|
Chris@16
|
641 // Note that the result iterator of the range must be convertible
|
Chris@16
|
642 // to BidiIter here.
|
Chris@16
|
643 BidiIter begin = boost::begin(rng), end = boost::end(rng);
|
Chris@16
|
644 // the state object holds matching state and
|
Chris@16
|
645 // is passed by reference to all the matchers
|
Chris@16
|
646 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
647 return detail::regex_search_impl(state, re);
|
Chris@16
|
648 }
|
Chris@16
|
649
|
Chris@16
|
650
|
Chris@16
|
651 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
652 // regex_replace
|
Chris@16
|
653 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
654
|
Chris@16
|
655 namespace detail
|
Chris@16
|
656 {
|
Chris@16
|
657 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
658 // regex_replace_impl
|
Chris@16
|
659 template<typename OutIter, typename BidiIter, typename Formatter>
|
Chris@16
|
660 inline OutIter regex_replace_impl
|
Chris@16
|
661 (
|
Chris@16
|
662 OutIter out
|
Chris@16
|
663 , BidiIter begin
|
Chris@16
|
664 , BidiIter end
|
Chris@16
|
665 , basic_regex<BidiIter> const &re
|
Chris@16
|
666 , Formatter const &format
|
Chris@16
|
667 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
668 )
|
Chris@16
|
669 {
|
Chris@16
|
670 using namespace regex_constants;
|
Chris@16
|
671 typedef detail::core_access<BidiIter> access;
|
Chris@16
|
672 BOOST_ASSERT(0 != re.regex_id());
|
Chris@16
|
673
|
Chris@16
|
674 BidiIter cur = begin;
|
Chris@16
|
675 match_results<BidiIter> what;
|
Chris@16
|
676 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
|
Chris@16
|
677 bool const yes_copy = (0 == (flags & format_no_copy));
|
Chris@16
|
678
|
Chris@16
|
679 if(detail::regex_search_impl(state, re))
|
Chris@16
|
680 {
|
Chris@16
|
681 if(yes_copy)
|
Chris@16
|
682 {
|
Chris@16
|
683 out = std::copy(cur, what[0].first, out);
|
Chris@16
|
684 }
|
Chris@16
|
685
|
Chris@16
|
686 out = what.format(out, format, flags);
|
Chris@16
|
687 cur = state.cur_ = state.next_search_ = what[0].second;
|
Chris@16
|
688
|
Chris@16
|
689 if(0 == (flags & format_first_only))
|
Chris@16
|
690 {
|
Chris@16
|
691 bool not_null = (0 == what.length());
|
Chris@16
|
692 state.reset(what, *access::get_regex_impl(re));
|
Chris@16
|
693 while(detail::regex_search_impl(state, re, not_null))
|
Chris@16
|
694 {
|
Chris@16
|
695 if(yes_copy)
|
Chris@16
|
696 {
|
Chris@16
|
697 out = std::copy(cur, what[0].first, out);
|
Chris@16
|
698 }
|
Chris@16
|
699
|
Chris@16
|
700 access::set_prefix_suffix(what, begin, end);
|
Chris@16
|
701 out = what.format(out, format, flags);
|
Chris@16
|
702 cur = state.cur_ = state.next_search_ = what[0].second;
|
Chris@16
|
703 not_null = (0 == what.length());
|
Chris@16
|
704 state.reset(what, *access::get_regex_impl(re));
|
Chris@16
|
705 }
|
Chris@16
|
706 }
|
Chris@16
|
707 }
|
Chris@16
|
708
|
Chris@16
|
709 if(yes_copy)
|
Chris@16
|
710 {
|
Chris@16
|
711 out = std::copy(cur, end, out);
|
Chris@16
|
712 }
|
Chris@16
|
713
|
Chris@16
|
714 return out;
|
Chris@16
|
715 }
|
Chris@16
|
716 } // namespace detail
|
Chris@16
|
717
|
Chris@16
|
718 /// \brief Build an output sequence given an input sequence, a regex, and a format string or
|
Chris@16
|
719 /// a formatter object, function, or expression.
|
Chris@16
|
720 ///
|
Chris@16
|
721 /// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
|
Chris@16
|
722 /// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
|
Chris@16
|
723 /// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
|
Chris@16
|
724 /// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
|
Chris@16
|
725 /// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
|
Chris@16
|
726 /// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
|
Chris@16
|
727 /// where \c last_m is a copy of the last match found.
|
Chris@16
|
728 ///
|
Chris@16
|
729 /// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
|
Chris@16
|
730 ///
|
Chris@16
|
731 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
|
Chris@16
|
732 /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
|
Chris@16
|
733 /// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
|
Chris@16
|
734 /// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
|
Chris@16
|
735 /// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
|
Chris@16
|
736 /// or else it is a null-terminated format string, or an expression template
|
Chris@16
|
737 /// representing a formatter lambda expression.
|
Chris@16
|
738 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
|
Chris@16
|
739 /// \param out An output iterator into which the output sequence is written.
|
Chris@16
|
740 /// \param begin The beginning of the input sequence.
|
Chris@16
|
741 /// \param end The end of the input sequence.
|
Chris@16
|
742 /// \param re The regular expression object to use.
|
Chris@16
|
743 /// \param format The format string used to format the replacement sequence,
|
Chris@16
|
744 /// or a formatter function, function object, or expression.
|
Chris@16
|
745 /// \param flags Optional match flags, used to control how the expression is matched against
|
Chris@16
|
746 /// the sequence. (See \c match_flag_type.)
|
Chris@16
|
747 /// \return The value of the output iterator after the output sequence has been written to it.
|
Chris@16
|
748 /// \throw regex_error on stack exhaustion or invalid format string.
|
Chris@16
|
749 template<typename OutIter, typename BidiIter, typename Formatter>
|
Chris@16
|
750 inline OutIter regex_replace
|
Chris@16
|
751 (
|
Chris@16
|
752 OutIter out
|
Chris@16
|
753 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
754 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
755 , basic_regex<BidiIter> const &re
|
Chris@16
|
756 , Formatter const &format
|
Chris@16
|
757 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
758 , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
|
Chris@16
|
759 )
|
Chris@16
|
760 {
|
Chris@16
|
761 // Default-constructed regexes match nothing
|
Chris@16
|
762 if(0 == re.regex_id())
|
Chris@16
|
763 {
|
Chris@16
|
764 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
765 {
|
Chris@16
|
766 out = std::copy(begin, end, out);
|
Chris@16
|
767 }
|
Chris@16
|
768
|
Chris@16
|
769 return out;
|
Chris@16
|
770 }
|
Chris@16
|
771
|
Chris@16
|
772 return detail::regex_replace_impl(out, begin, end, re, format, flags);
|
Chris@16
|
773 }
|
Chris@16
|
774
|
Chris@16
|
775 /// \overload
|
Chris@16
|
776 ///
|
Chris@16
|
777 template<typename OutIter, typename BidiIter>
|
Chris@16
|
778 inline OutIter regex_replace
|
Chris@16
|
779 (
|
Chris@16
|
780 OutIter out
|
Chris@16
|
781 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
|
Chris@16
|
782 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
|
Chris@16
|
783 , basic_regex<BidiIter> const &re
|
Chris@16
|
784 , typename iterator_value<BidiIter>::type const *format
|
Chris@16
|
785 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
786 )
|
Chris@16
|
787 {
|
Chris@16
|
788 // Default-constructed regexes match nothing
|
Chris@16
|
789 if(0 == re.regex_id())
|
Chris@16
|
790 {
|
Chris@16
|
791 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
792 {
|
Chris@16
|
793 out = std::copy(begin, end, out);
|
Chris@16
|
794 }
|
Chris@16
|
795
|
Chris@16
|
796 return out;
|
Chris@16
|
797 }
|
Chris@16
|
798
|
Chris@16
|
799 return detail::regex_replace_impl(out, begin, end, re, format, flags);
|
Chris@16
|
800 }
|
Chris@16
|
801
|
Chris@16
|
802 /// \overload
|
Chris@16
|
803 ///
|
Chris@16
|
804 template<typename BidiContainer, typename BidiIter, typename Formatter>
|
Chris@16
|
805 inline BidiContainer regex_replace
|
Chris@16
|
806 (
|
Chris@16
|
807 BidiContainer &str
|
Chris@16
|
808 , basic_regex<BidiIter> const &re
|
Chris@16
|
809 , Formatter const &format
|
Chris@16
|
810 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
811 , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
|
Chris@16
|
812 )
|
Chris@16
|
813 {
|
Chris@16
|
814 BidiContainer result;
|
Chris@16
|
815 // Note that the result iterator of the range must be convertible
|
Chris@16
|
816 // to BidiIter here.
|
Chris@16
|
817 BidiIter begin = boost::begin(str), end = boost::end(str);
|
Chris@16
|
818
|
Chris@16
|
819 // Default-constructed regexes match nothing
|
Chris@16
|
820 if(0 == re.regex_id())
|
Chris@16
|
821 {
|
Chris@16
|
822 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
823 {
|
Chris@16
|
824 std::copy(begin, end, std::back_inserter(result));
|
Chris@16
|
825 }
|
Chris@16
|
826
|
Chris@16
|
827 return result;
|
Chris@16
|
828 }
|
Chris@16
|
829
|
Chris@16
|
830 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
|
Chris@16
|
831 return result;
|
Chris@16
|
832 }
|
Chris@16
|
833
|
Chris@16
|
834 /// \overload
|
Chris@16
|
835 ///
|
Chris@16
|
836 template<typename BidiContainer, typename BidiIter, typename Formatter>
|
Chris@16
|
837 inline BidiContainer regex_replace
|
Chris@16
|
838 (
|
Chris@16
|
839 BidiContainer const &str
|
Chris@16
|
840 , basic_regex<BidiIter> const &re
|
Chris@16
|
841 , Formatter const &format
|
Chris@16
|
842 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
843 , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
|
Chris@16
|
844 )
|
Chris@16
|
845 {
|
Chris@16
|
846 BidiContainer result;
|
Chris@16
|
847 // Note that the result iterator of the range must be convertible
|
Chris@16
|
848 // to BidiIter here.
|
Chris@16
|
849 BidiIter begin = boost::begin(str), end = boost::end(str);
|
Chris@16
|
850
|
Chris@16
|
851 // Default-constructed regexes match nothing
|
Chris@16
|
852 if(0 == re.regex_id())
|
Chris@16
|
853 {
|
Chris@16
|
854 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
855 {
|
Chris@16
|
856 std::copy(begin, end, std::back_inserter(result));
|
Chris@16
|
857 }
|
Chris@16
|
858
|
Chris@16
|
859 return result;
|
Chris@16
|
860 }
|
Chris@16
|
861
|
Chris@16
|
862 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
|
Chris@16
|
863 return result;
|
Chris@16
|
864 }
|
Chris@16
|
865
|
Chris@16
|
866 /// \overload
|
Chris@16
|
867 ///
|
Chris@16
|
868 template<typename Char, typename Formatter>
|
Chris@16
|
869 inline std::basic_string<typename remove_const<Char>::type> regex_replace
|
Chris@16
|
870 (
|
Chris@16
|
871 BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
|
Chris@16
|
872 , basic_regex<Char *> const &re
|
Chris@16
|
873 , Formatter const &format
|
Chris@16
|
874 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
875 , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
|
Chris@16
|
876 )
|
Chris@16
|
877 {
|
Chris@16
|
878 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
879 std::basic_string<char_type> result;
|
Chris@16
|
880
|
Chris@16
|
881 // Default-constructed regexes match nothing
|
Chris@16
|
882 if(0 == re.regex_id())
|
Chris@16
|
883 {
|
Chris@16
|
884 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
885 {
|
Chris@16
|
886 result = str;
|
Chris@16
|
887 }
|
Chris@16
|
888
|
Chris@16
|
889 return result;
|
Chris@16
|
890 }
|
Chris@16
|
891
|
Chris@16
|
892 Char *end = str + std::char_traits<char_type>::length(str);
|
Chris@16
|
893 detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
|
Chris@16
|
894 return result;
|
Chris@16
|
895 }
|
Chris@16
|
896
|
Chris@16
|
897 /// \overload
|
Chris@16
|
898 ///
|
Chris@16
|
899 template<typename BidiContainer, typename BidiIter>
|
Chris@16
|
900 inline BidiContainer regex_replace
|
Chris@16
|
901 (
|
Chris@16
|
902 BidiContainer &str
|
Chris@16
|
903 , basic_regex<BidiIter> const &re
|
Chris@16
|
904 , typename iterator_value<BidiIter>::type const *format
|
Chris@16
|
905 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
906 , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
|
Chris@16
|
907 )
|
Chris@16
|
908 {
|
Chris@16
|
909 BidiContainer result;
|
Chris@16
|
910 // Note that the result iterator of the range must be convertible
|
Chris@16
|
911 // to BidiIter here.
|
Chris@16
|
912 BidiIter begin = boost::begin(str), end = boost::end(str);
|
Chris@16
|
913
|
Chris@16
|
914 // Default-constructed regexes match nothing
|
Chris@16
|
915 if(0 == re.regex_id())
|
Chris@16
|
916 {
|
Chris@16
|
917 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
918 {
|
Chris@16
|
919 std::copy(begin, end, std::back_inserter(result));
|
Chris@16
|
920 }
|
Chris@16
|
921
|
Chris@16
|
922 return result;
|
Chris@16
|
923 }
|
Chris@16
|
924
|
Chris@16
|
925 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
|
Chris@16
|
926 return result;
|
Chris@16
|
927 }
|
Chris@16
|
928
|
Chris@16
|
929 /// \overload
|
Chris@16
|
930 ///
|
Chris@16
|
931 template<typename BidiContainer, typename BidiIter>
|
Chris@16
|
932 inline BidiContainer regex_replace
|
Chris@16
|
933 (
|
Chris@16
|
934 BidiContainer const &str
|
Chris@16
|
935 , basic_regex<BidiIter> const &re
|
Chris@16
|
936 , typename iterator_value<BidiIter>::type const *format
|
Chris@16
|
937 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
938 , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
|
Chris@16
|
939 )
|
Chris@16
|
940 {
|
Chris@16
|
941 BidiContainer result;
|
Chris@16
|
942 // Note that the result iterator of the range must be convertible
|
Chris@16
|
943 // to BidiIter here.
|
Chris@16
|
944 BidiIter begin = boost::begin(str), end = boost::end(str);
|
Chris@16
|
945
|
Chris@16
|
946 // Default-constructed regexes match nothing
|
Chris@16
|
947 if(0 == re.regex_id())
|
Chris@16
|
948 {
|
Chris@16
|
949 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
950 {
|
Chris@16
|
951 std::copy(begin, end, std::back_inserter(result));
|
Chris@16
|
952 }
|
Chris@16
|
953
|
Chris@16
|
954 return result;
|
Chris@16
|
955 }
|
Chris@16
|
956
|
Chris@16
|
957 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
|
Chris@16
|
958 return result;
|
Chris@16
|
959 }
|
Chris@16
|
960
|
Chris@16
|
961 /// \overload
|
Chris@16
|
962 ///
|
Chris@16
|
963 template<typename Char>
|
Chris@16
|
964 inline std::basic_string<typename remove_const<Char>::type> regex_replace
|
Chris@16
|
965 (
|
Chris@16
|
966 BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
|
Chris@16
|
967 , basic_regex<Char *> const &re
|
Chris@16
|
968 , typename add_const<Char>::type *format
|
Chris@16
|
969 , regex_constants::match_flag_type flags = regex_constants::match_default
|
Chris@16
|
970 )
|
Chris@16
|
971 {
|
Chris@16
|
972 typedef typename remove_const<Char>::type char_type;
|
Chris@16
|
973 std::basic_string<char_type> result;
|
Chris@16
|
974
|
Chris@16
|
975 // Default-constructed regexes match nothing
|
Chris@16
|
976 if(0 == re.regex_id())
|
Chris@16
|
977 {
|
Chris@16
|
978 if((0 == (flags & regex_constants::format_no_copy)))
|
Chris@16
|
979 {
|
Chris@16
|
980 result = str;
|
Chris@16
|
981 }
|
Chris@16
|
982
|
Chris@16
|
983 return result;
|
Chris@16
|
984 }
|
Chris@16
|
985
|
Chris@16
|
986 Char *end = str + std::char_traits<char_type>::length(str);
|
Chris@16
|
987 detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
|
Chris@16
|
988 return result;
|
Chris@16
|
989 }
|
Chris@16
|
990
|
Chris@16
|
991 }} // namespace boost::xpressive
|
Chris@16
|
992
|
Chris@16
|
993 #endif
|