1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file regex_algorithms.hpp
3 /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
6 // Software License, Version 1.0. (See accompanying file
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 #ifndef BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
10 #define BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
12 // MS compatible compilers support #pragma once
13 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
19 #include <boost/mpl/or.hpp>
20 #include <boost/range/end.hpp>
21 #include <boost/range/begin.hpp>
22 #include <boost/mpl/identity.hpp>
23 #include <boost/utility/enable_if.hpp>
24 #include <boost/type_traits/add_const.hpp>
25 #include <boost/type_traits/is_pointer.hpp>
26 #include <boost/type_traits/remove_const.hpp>
27 #include <boost/xpressive/match_results.hpp>
28 #include <boost/xpressive/detail/detail_fwd.hpp>
29 #include <boost/xpressive/detail/core/state.hpp>
30 #include <boost/xpressive/detail/utility/save_restore.hpp>
34 #define BOOST_XPR_NONDEDUCED_TYPE_(x) typename mpl::identity<x>::type
36 namespace boost
{ namespace xpressive
39 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////////////////
47 template<typename BidiIter
>
48 inline bool regex_match_impl
50 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
51 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
52 , match_results
<BidiIter
> &what
53 , basic_regex
<BidiIter
> const &re
54 , regex_constants::match_flag_type flags
= regex_constants::match_default
57 typedef detail::core_access
<BidiIter
> access
;
58 BOOST_ASSERT(0 != re
.regex_id());
60 // the state object holds matching state and
61 // is passed by reference to all the matchers
62 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
63 state
.flags_
.match_all_
= true;
64 state
.sub_match(0).begin_
= begin
;
66 if(access::match(re
, state
))
68 access::set_prefix_suffix(what
, begin
, end
);
72 // handle partial matches
73 else if(state
.found_partial_match_
&& 0 != (flags
& regex_constants::match_partial
))
75 state
.set_partial_match();
84 /// \brief See if a regex matches a sequence from beginning to end.
86 /// Determines whether there is an exact match between the regular expression \c re,
87 /// and all of the sequence <tt>[begin, end)</tt>.
89 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
90 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
91 /// \param begin The beginning of the sequence.
92 /// \param end The end of the sequence.
93 /// \param what The \c match_results struct into which the sub_matches will be written
94 /// \param re The regular expression object to use
95 /// \param flags Optional match flags, used to control how the expression is matched
96 /// against the sequence. (See \c match_flag_type.)
97 /// \return \c true if a match is found, \c false otherwise
98 /// \throw \c regex_error on stack exhaustion
99 template<typename BidiIter
>
100 inline bool regex_match
102 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
103 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
104 , match_results
<BidiIter
> &what
105 , basic_regex
<BidiIter
> const &re
106 , regex_constants::match_flag_type flags
= regex_constants::match_default
109 typedef detail::core_access
<BidiIter
> access
;
111 if(0 == re
.regex_id())
117 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
122 template<typename BidiIter
>
123 inline bool regex_match
125 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
126 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
127 , basic_regex
<BidiIter
> const &re
128 , regex_constants::match_flag_type flags
= regex_constants::match_default
131 if(0 == re
.regex_id())
136 // BUGBUG this is inefficient
137 match_results
<BidiIter
> what
;
138 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
143 template<typename Char
>
144 inline bool regex_match
146 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *begin
147 , match_results
<Char
*> &what
148 , basic_regex
<Char
*> const &re
149 , regex_constants::match_flag_type flags
= regex_constants::match_default
152 typedef detail::core_access
<Char
*> access
;
154 if(0 == re
.regex_id())
160 // BUGBUG this is inefficient
161 typedef typename remove_const
<Char
>::type char_type
;
162 Char
*end
= begin
+ std::char_traits
<char_type
>::length(begin
);
163 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
168 template<typename BidiRange
, typename BidiIter
>
169 inline bool regex_match
172 , match_results
<BidiIter
> &what
173 , basic_regex
<BidiIter
> const &re
174 , regex_constants::match_flag_type flags
= regex_constants::match_default
175 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
178 typedef detail::core_access
<BidiIter
> access
;
180 if(0 == re
.regex_id())
186 // Note that the result iterator of the range must be convertible
188 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
189 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
194 template<typename BidiRange
, typename BidiIter
>
195 inline bool regex_match
198 , match_results
<BidiIter
> &what
199 , basic_regex
<BidiIter
> const &re
200 , regex_constants::match_flag_type flags
= regex_constants::match_default
201 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
204 typedef detail::core_access
<BidiIter
> access
;
206 if(0 == re
.regex_id())
212 // Note that the result iterator of the range must be convertible
214 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
215 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
220 template<typename Char
>
221 inline bool regex_match
223 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *begin
224 , basic_regex
<Char
*> const &re
225 , regex_constants::match_flag_type flags
= regex_constants::match_default
228 if(0 == re
.regex_id())
233 // BUGBUG this is inefficient
234 match_results
<Char
*> what
;
235 typedef typename remove_const
<Char
>::type char_type
;
236 Char
*end
= begin
+ std::char_traits
<char_type
>::length(begin
);
237 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
242 template<typename BidiRange
, typename BidiIter
>
243 inline bool regex_match
246 , basic_regex
<BidiIter
> const &re
247 , regex_constants::match_flag_type flags
= regex_constants::match_default
248 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
251 if(0 == re
.regex_id())
256 // BUGBUG this is inefficient
257 match_results
<BidiIter
> what
;
258 // Note that the result iterator of the range must be convertible
260 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
261 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
266 template<typename BidiRange
, typename BidiIter
>
267 inline bool regex_match
270 , basic_regex
<BidiIter
> const &re
271 , regex_constants::match_flag_type flags
= regex_constants::match_default
272 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
275 if(0 == re
.regex_id())
280 // BUGBUG this is inefficient
281 match_results
<BidiIter
> what
;
282 // Note that the result iterator of the range must be convertible
284 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
285 return detail::regex_match_impl(begin
, end
, what
, re
, flags
);
289 ///////////////////////////////////////////////////////////////////////////////
291 ///////////////////////////////////////////////////////////////////////////////
295 ///////////////////////////////////////////////////////////////////////////////
297 template<typename BidiIter
>
298 inline bool regex_search_impl
300 match_state
<BidiIter
> &state
301 , basic_regex
<BidiIter
> const &re
302 , bool not_initial_null
= false
305 typedef core_access
<BidiIter
> access
;
306 typedef typename iterator_value
<BidiIter
>::type char_type
;
307 match_results
<BidiIter
> &what
= *state
.context_
.results_ptr_
;
308 BOOST_ASSERT(0 != re
.regex_id());
310 bool const partial_ok
= state
.flags_
.match_partial_
;
311 save_restore
<bool> not_null(state
.flags_
.match_not_null_
, state
.flags_
.match_not_null_
|| not_initial_null
);
312 state
.flags_
.match_prev_avail_
= state
.flags_
.match_prev_avail_
|| !state
.bos();
314 regex_impl
<BidiIter
> const &impl
= *access::get_regex_impl(re
);
315 BidiIter
const begin
= state
.cur_
, end
= state
.end_
;
316 BidiIter
&sub0begin
= state
.sub_match(0).begin_
;
317 sub0begin
= state
.cur_
;
319 // If match_continuous is set, we only need to check for a match at the current position
320 if(state
.flags_
.match_continuous_
)
322 if(access::match(re
, state
))
324 access::set_prefix_suffix(what
, begin
, end
);
328 // handle partial matches
329 else if(partial_ok
&& state
.found_partial_match_
)
331 state
.set_partial_match();
336 // If we have a finder, use it to find where a potential match can start
337 else if(impl
.finder_
&& (!partial_ok
|| impl
.finder_
->ok_for_partial_matches()))
339 finder
<BidiIter
> const &find
= *impl
.finder_
;
342 if(state
.cur_
!= begin
)
349 sub0begin
= state
.cur_
;
350 if(access::match(re
, state
))
352 access::set_prefix_suffix(what
, begin
, end
);
356 // handle partial matches
357 else if(partial_ok
&& state
.found_partial_match_
)
359 state
.set_partial_match();
363 BOOST_ASSERT(state
.cur_
== sub0begin
);
366 while(state
.cur_
!= state
.end_
&& (++state
.cur_
, find(state
)));
370 // Otherwise, use brute force search at every position.
375 if(access::match(re
, state
))
377 access::set_prefix_suffix(what
, begin
, end
);
381 // handle partial matches
382 else if(partial_ok
&& state
.found_partial_match_
)
384 state
.set_partial_match();
388 else if(end
== sub0begin
)
393 BOOST_ASSERT(state
.cur_
== sub0begin
);
394 state
.cur_
= ++sub0begin
;
402 } // namespace detail
405 /// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
406 /// that matches the regular expression \c re.
408 /// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
409 /// the regular expression \c re.
411 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
412 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
413 /// \param begin The beginning of the sequence
414 /// \param end The end of the sequence
415 /// \param what The \c match_results struct into which the sub_matches will be written
416 /// \param re The regular expression object to use
417 /// \param flags Optional match flags, used to control how the expression is matched against
418 /// the sequence. (See \c match_flag_type.)
419 /// \return \c true if a match is found, \c false otherwise
420 /// \throw \c regex_error on stack exhaustion
421 template<typename BidiIter
>
422 inline bool regex_search
424 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
425 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
426 , match_results
<BidiIter
> &what
427 , basic_regex
<BidiIter
> const &re
428 , regex_constants::match_flag_type flags
= regex_constants::match_default
431 typedef detail::core_access
<BidiIter
> access
;
433 // a default-constructed regex matches nothing
434 if(0 == re
.regex_id())
440 // the state object holds matching state and
441 // is passed by reference to all the matchers
442 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
443 return detail::regex_search_impl(state
, re
);
448 template<typename BidiIter
>
449 inline bool regex_search
451 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
452 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
453 , basic_regex
<BidiIter
> const &re
454 , regex_constants::match_flag_type flags
= regex_constants::match_default
457 typedef detail::core_access
<BidiIter
> access
;
459 // a default-constructed regex matches nothing
460 if(0 == re
.regex_id())
465 // BUGBUG this is inefficient
466 match_results
<BidiIter
> what
;
467 // the state object holds matching state and
468 // is passed by reference to all the matchers
469 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
470 return detail::regex_search_impl(state
, re
);
475 template<typename Char
>
476 inline bool regex_search
478 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *begin
479 , match_results
<Char
*> &what
480 , basic_regex
<Char
*> const &re
481 , regex_constants::match_flag_type flags
= regex_constants::match_default
484 typedef detail::core_access
<Char
*> access
;
486 // a default-constructed regex matches nothing
487 if(0 == re
.regex_id())
493 // BUGBUG this is inefficient
494 typedef typename remove_const
<Char
>::type char_type
;
495 Char
*end
= begin
+ std::char_traits
<char_type
>::length(begin
);
496 // the state object holds matching state and
497 // is passed by reference to all the matchers
498 detail::match_state
<Char
*> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
499 return detail::regex_search_impl(state
, re
);
504 template<typename BidiRange
, typename BidiIter
>
505 inline bool regex_search
508 , match_results
<BidiIter
> &what
509 , basic_regex
<BidiIter
> const &re
510 , regex_constants::match_flag_type flags
= regex_constants::match_default
511 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
514 typedef detail::core_access
<BidiIter
> access
;
516 // a default-constructed regex matches nothing
517 if(0 == re
.regex_id())
523 // Note that the result iterator of the range must be convertible
525 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
526 // the state object holds matching state and
527 // is passed by reference to all the matchers
528 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
529 return detail::regex_search_impl(state
, re
);
534 template<typename BidiRange
, typename BidiIter
>
535 inline bool regex_search
538 , match_results
<BidiIter
> &what
539 , basic_regex
<BidiIter
> const &re
540 , regex_constants::match_flag_type flags
= regex_constants::match_default
541 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
544 typedef detail::core_access
<BidiIter
> access
;
546 // a default-constructed regex matches nothing
547 if(0 == re
.regex_id())
553 // Note that the result iterator of the range must be convertible
555 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
556 // the state object holds matching state and
557 // is passed by reference to all the matchers
558 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
559 return detail::regex_search_impl(state
, re
);
564 template<typename Char
>
565 inline bool regex_search
567 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *begin
568 , basic_regex
<Char
*> const &re
569 , regex_constants::match_flag_type flags
= regex_constants::match_default
572 typedef detail::core_access
<Char
*> access
;
574 // a default-constructed regex matches nothing
575 if(0 == re
.regex_id())
580 // BUGBUG this is inefficient
581 match_results
<Char
*> what
;
582 // BUGBUG this is inefficient
583 typedef typename remove_const
<Char
>::type char_type
;
584 Char
*end
= begin
+ std::char_traits
<char_type
>::length(begin
);
585 // the state object holds matching state and
586 // is passed by reference to all the matchers
587 detail::match_state
<Char
*> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
588 return detail::regex_search_impl(state
, re
);
593 template<typename BidiRange
, typename BidiIter
>
594 inline bool regex_search
597 , basic_regex
<BidiIter
> const &re
598 , regex_constants::match_flag_type flags
= regex_constants::match_default
599 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
602 typedef detail::core_access
<BidiIter
> access
;
604 // a default-constructed regex matches nothing
605 if(0 == re
.regex_id())
610 // BUGBUG this is inefficient
611 match_results
<BidiIter
> what
;
612 // Note that the result iterator of the range must be convertible
614 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
615 // the state object holds matching state and
616 // is passed by reference to all the matchers
617 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
618 return detail::regex_search_impl(state
, re
);
623 template<typename BidiRange
, typename BidiIter
>
624 inline bool regex_search
627 , basic_regex
<BidiIter
> const &re
628 , regex_constants::match_flag_type flags
= regex_constants::match_default
629 , typename disable_if
<detail::is_char_ptr
<BidiRange
> >::type
* = 0
632 typedef detail::core_access
<BidiIter
> access
;
634 // a default-constructed regex matches nothing
635 if(0 == re
.regex_id())
640 // BUGBUG this is inefficient
641 match_results
<BidiIter
> what
;
642 // Note that the result iterator of the range must be convertible
644 BidiIter begin
= boost::begin(rng
), end
= boost::end(rng
);
645 // the state object holds matching state and
646 // is passed by reference to all the matchers
647 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
648 return detail::regex_search_impl(state
, re
);
652 ///////////////////////////////////////////////////////////////////////////////
654 ///////////////////////////////////////////////////////////////////////////////
658 ///////////////////////////////////////////////////////////////////////////////
659 // regex_replace_impl
660 template<typename OutIter
, typename BidiIter
, typename Formatter
>
661 inline OutIter regex_replace_impl
666 , basic_regex
<BidiIter
> const &re
667 , Formatter
const &format
668 , regex_constants::match_flag_type flags
= regex_constants::match_default
671 using namespace regex_constants
;
672 typedef detail::core_access
<BidiIter
> access
;
673 BOOST_ASSERT(0 != re
.regex_id());
675 BidiIter cur
= begin
;
676 match_results
<BidiIter
> what
;
677 detail::match_state
<BidiIter
> state(begin
, end
, what
, *access::get_regex_impl(re
), flags
);
678 bool const yes_copy
= (0 == (flags
& format_no_copy
));
680 if(detail::regex_search_impl(state
, re
))
684 out
= std::copy(cur
, what
[0].first
, out
);
687 out
= what
.format(out
, format
, flags
);
688 cur
= state
.cur_
= state
.next_search_
= what
[0].second
;
690 if(0 == (flags
& format_first_only
))
692 bool not_null
= (0 == what
.length());
693 state
.reset(what
, *access::get_regex_impl(re
));
694 while(detail::regex_search_impl(state
, re
, not_null
))
698 out
= std::copy(cur
, what
[0].first
, out
);
701 access::set_prefix_suffix(what
, begin
, end
);
702 out
= what
.format(out
, format
, flags
);
703 cur
= state
.cur_
= state
.next_search_
= what
[0].second
;
704 not_null
= (0 == what
.length());
705 state
.reset(what
, *access::get_regex_impl(re
));
712 out
= std::copy(cur
, end
, out
);
717 } // namespace detail
719 /// \brief Build an output sequence given an input sequence, a regex, and a format string or
720 /// a formatter object, function, or expression.
722 /// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
723 /// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
724 /// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
725 /// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
726 /// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
727 /// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
728 /// where \c last_m is a copy of the last match found.
730 /// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
732 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
733 /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
734 /// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
735 /// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
736 /// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
737 /// or else it is a null-terminated format string, or an expression template
738 /// representing a formatter lambda expression.
739 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
740 /// \param out An output iterator into which the output sequence is written.
741 /// \param begin The beginning of the input sequence.
742 /// \param end The end of the input sequence.
743 /// \param re The regular expression object to use.
744 /// \param format The format string used to format the replacement sequence,
745 /// or a formatter function, function object, or expression.
746 /// \param flags Optional match flags, used to control how the expression is matched against
747 /// the sequence. (See \c match_flag_type.)
748 /// \return The value of the output iterator after the output sequence has been written to it.
749 /// \throw \c regex_error on stack exhaustion or invalid format string.
750 template<typename OutIter
, typename BidiIter
, typename Formatter
>
751 inline OutIter regex_replace
754 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
755 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
756 , basic_regex
<BidiIter
> const &re
757 , Formatter
const &format
758 , regex_constants::match_flag_type flags
= regex_constants::match_default
759 , typename disable_if
<detail::is_char_ptr
<Formatter
> >::type
* = 0
762 // Default-constructed regexes match nothing
763 if(0 == re
.regex_id())
765 if((0 == (flags
& regex_constants::format_no_copy
)))
767 out
= std::copy(begin
, end
, out
);
773 return detail::regex_replace_impl(out
, begin
, end
, re
, format
, flags
);
778 template<typename OutIter
, typename BidiIter
>
779 inline OutIter regex_replace
782 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) begin
783 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter
) end
784 , basic_regex
<BidiIter
> const &re
785 , typename iterator_value
<BidiIter
>::type
const *format
786 , regex_constants::match_flag_type flags
= regex_constants::match_default
789 // Default-constructed regexes match nothing
790 if(0 == re
.regex_id())
792 if((0 == (flags
& regex_constants::format_no_copy
)))
794 out
= std::copy(begin
, end
, out
);
800 return detail::regex_replace_impl(out
, begin
, end
, re
, format
, flags
);
805 template<typename BidiContainer
, typename BidiIter
, typename Formatter
>
806 inline BidiContainer regex_replace
809 , basic_regex
<BidiIter
> const &re
810 , Formatter
const &format
811 , regex_constants::match_flag_type flags
= regex_constants::match_default
812 , typename disable_if
<mpl::or_
<detail::is_char_ptr
<BidiContainer
>, detail::is_char_ptr
<Formatter
> > >::type
* = 0
815 BidiContainer result
;
816 // Note that the result iterator of the range must be convertible
818 BidiIter begin
= boost::begin(str
), end
= boost::end(str
);
820 // Default-constructed regexes match nothing
821 if(0 == re
.regex_id())
823 if((0 == (flags
& regex_constants::format_no_copy
)))
825 std::copy(begin
, end
, std::back_inserter(result
));
831 detail::regex_replace_impl(std::back_inserter(result
), begin
, end
, re
, format
, flags
);
837 template<typename BidiContainer
, typename BidiIter
, typename Formatter
>
838 inline BidiContainer regex_replace
840 BidiContainer
const &str
841 , basic_regex
<BidiIter
> const &re
842 , Formatter
const &format
843 , regex_constants::match_flag_type flags
= regex_constants::match_default
844 , typename disable_if
<mpl::or_
<detail::is_char_ptr
<BidiContainer
>, detail::is_char_ptr
<Formatter
> > >::type
* = 0
847 BidiContainer result
;
848 // Note that the result iterator of the range must be convertible
850 BidiIter begin
= boost::begin(str
), end
= boost::end(str
);
852 // Default-constructed regexes match nothing
853 if(0 == re
.regex_id())
855 if((0 == (flags
& regex_constants::format_no_copy
)))
857 std::copy(begin
, end
, std::back_inserter(result
));
863 detail::regex_replace_impl(std::back_inserter(result
), begin
, end
, re
, format
, flags
);
869 template<typename Char
, typename Formatter
>
870 inline std::basic_string
<typename remove_const
<Char
>::type
> regex_replace
872 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *str
873 , basic_regex
<Char
*> const &re
874 , Formatter
const &format
875 , regex_constants::match_flag_type flags
= regex_constants::match_default
876 , typename disable_if
<detail::is_char_ptr
<Formatter
> >::type
* = 0
879 typedef typename remove_const
<Char
>::type char_type
;
880 std::basic_string
<char_type
> result
;
882 // Default-constructed regexes match nothing
883 if(0 == re
.regex_id())
885 if((0 == (flags
& regex_constants::format_no_copy
)))
893 Char
*end
= str
+ std::char_traits
<char_type
>::length(str
);
894 detail::regex_replace_impl(std::back_inserter(result
), str
, end
, re
, format
, flags
);
900 template<typename BidiContainer
, typename BidiIter
>
901 inline BidiContainer regex_replace
904 , basic_regex
<BidiIter
> const &re
905 , typename iterator_value
<BidiIter
>::type
const *format
906 , regex_constants::match_flag_type flags
= regex_constants::match_default
907 , typename disable_if
<detail::is_char_ptr
<BidiContainer
> >::type
* = 0
910 BidiContainer result
;
911 // Note that the result iterator of the range must be convertible
913 BidiIter begin
= boost::begin(str
), end
= boost::end(str
);
915 // Default-constructed regexes match nothing
916 if(0 == re
.regex_id())
918 if((0 == (flags
& regex_constants::format_no_copy
)))
920 std::copy(begin
, end
, std::back_inserter(result
));
926 detail::regex_replace_impl(std::back_inserter(result
), begin
, end
, re
, format
, flags
);
932 template<typename BidiContainer
, typename BidiIter
>
933 inline BidiContainer regex_replace
935 BidiContainer
const &str
936 , basic_regex
<BidiIter
> const &re
937 , typename iterator_value
<BidiIter
>::type
const *format
938 , regex_constants::match_flag_type flags
= regex_constants::match_default
939 , typename disable_if
<detail::is_char_ptr
<BidiContainer
> >::type
* = 0
942 BidiContainer result
;
943 // Note that the result iterator of the range must be convertible
945 BidiIter begin
= boost::begin(str
), end
= boost::end(str
);
947 // Default-constructed regexes match nothing
948 if(0 == re
.regex_id())
950 if((0 == (flags
& regex_constants::format_no_copy
)))
952 std::copy(begin
, end
, std::back_inserter(result
));
958 detail::regex_replace_impl(std::back_inserter(result
), begin
, end
, re
, format
, flags
);
964 template<typename Char
>
965 inline std::basic_string
<typename remove_const
<Char
>::type
> regex_replace
967 BOOST_XPR_NONDEDUCED_TYPE_(Char
) *str
968 , basic_regex
<Char
*> const &re
969 , typename add_const
<Char
>::type
*format
970 , regex_constants::match_flag_type flags
= regex_constants::match_default
973 typedef typename remove_const
<Char
>::type char_type
;
974 std::basic_string
<char_type
> result
;
976 // Default-constructed regexes match nothing
977 if(0 == re
.regex_id())
979 if((0 == (flags
& regex_constants::format_no_copy
)))
987 Char
*end
= str
+ std::char_traits
<char_type
>::length(str
);
988 detail::regex_replace_impl(std::back_inserter(result
), str
, end
, re
, format
, flags
);
992 }} // namespace boost::xpressive