Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:54

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file regex_algorithms.hpp
0003 /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
0004 //
0005 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0006 //  Software License, Version 1.0. (See accompanying file
0007 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #ifndef BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
0010 #define BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
0011 
0012 // MS compatible compilers support #pragma once
0013 #if defined(_MSC_VER)
0014 # pragma once
0015 #endif
0016 
0017 #include <string>
0018 #include <iterator>
0019 #include <boost/mpl/or.hpp>
0020 #include <boost/range/end.hpp>
0021 #include <boost/range/begin.hpp>
0022 #include <boost/mpl/identity.hpp>
0023 #include <boost/utility/enable_if.hpp>
0024 #include <boost/type_traits/add_const.hpp>
0025 #include <boost/type_traits/is_pointer.hpp>
0026 #include <boost/type_traits/remove_const.hpp>
0027 #include <boost/xpressive/match_results.hpp>
0028 #include <boost/xpressive/detail/detail_fwd.hpp>
0029 #include <boost/xpressive/detail/core/state.hpp>
0030 #include <boost/xpressive/detail/utility/save_restore.hpp>
0031 
0032 /// INTERNAL ONLY
0033 ///
0034 #define BOOST_XPR_NONDEDUCED_TYPE_(x) typename mpl::identity<x>::type
0035 
0036 namespace boost { namespace xpressive
0037 {
0038 
0039 ///////////////////////////////////////////////////////////////////////////////
0040 // regex_match
0041 ///////////////////////////////////////////////////////////////////////////////
0042 
0043 namespace detail
0044 {
0045     ///////////////////////////////////////////////////////////////////////////////
0046     // regex_match_impl
0047     template<typename BidiIter>
0048     inline bool regex_match_impl
0049     (
0050         BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0051       , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0052       , match_results<BidiIter> &what
0053       , basic_regex<BidiIter> const &re
0054       , regex_constants::match_flag_type flags = regex_constants::match_default
0055     )
0056     {
0057         typedef detail::core_access<BidiIter> access;
0058         BOOST_ASSERT(0 != re.regex_id());
0059 
0060         // the state object holds matching state and
0061         // is passed by reference to all the matchers
0062         detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0063         state.flags_.match_all_ = true;
0064         state.sub_match(0).begin_ = begin;
0065 
0066         if(access::match(re, state))
0067         {
0068             access::set_prefix_suffix(what, begin, end);
0069             return true;
0070         }
0071 
0072         // handle partial matches
0073         else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
0074         {
0075             state.set_partial_match();
0076             return true;
0077         }
0078 
0079         access::reset(what);
0080         return false;
0081     }
0082 } // namespace detail
0083 
0084 /// \brief See if a regex matches a sequence from beginning to end.
0085 ///
0086 /// Determines whether there is an exact match between the regular expression \c re,
0087 /// and all of the sequence <tt>[begin, end)</tt>.
0088 ///
0089 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
0090 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
0091 /// \param begin The beginning of the sequence.
0092 /// \param end The end of the sequence.
0093 /// \param what The \c match_results struct into which the sub_matches will be written
0094 /// \param re The regular expression object to use
0095 /// \param flags Optional match flags, used to control how the expression is matched
0096 ///        against the sequence. (See \c match_flag_type.)
0097 /// \return \c true if a match is found, \c false otherwise
0098 /// \throw regex_error on stack exhaustion
0099 template<typename BidiIter>
0100 inline bool regex_match
0101 (
0102     BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0103   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0104   , match_results<BidiIter> &what
0105   , basic_regex<BidiIter> const &re
0106   , regex_constants::match_flag_type flags = regex_constants::match_default
0107 )
0108 {
0109     typedef detail::core_access<BidiIter> access;
0110 
0111     if(0 == re.regex_id())
0112     {
0113         access::reset(what);
0114         return false;
0115     }
0116 
0117     return detail::regex_match_impl(begin, end, what, re, flags);
0118 }
0119 
0120 /// \overload
0121 ///
0122 template<typename BidiIter>
0123 inline bool regex_match
0124 (
0125     BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0126   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0127   , basic_regex<BidiIter> const &re
0128   , regex_constants::match_flag_type flags = regex_constants::match_default
0129 )
0130 {
0131     if(0 == re.regex_id())
0132     {
0133         return false;
0134     }
0135 
0136     // BUGBUG this is inefficient
0137     match_results<BidiIter> what;
0138     return detail::regex_match_impl(begin, end, what, re, flags);
0139 }
0140 
0141 /// \overload
0142 ///
0143 template<typename Char>
0144 inline bool regex_match
0145 (
0146     BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
0147   , match_results<Char *> &what
0148   , basic_regex<Char *> const &re
0149   , regex_constants::match_flag_type flags = regex_constants::match_default
0150 )
0151 {
0152     typedef detail::core_access<Char *> access;
0153 
0154     if(0 == re.regex_id())
0155     {
0156         access::reset(what);
0157         return false;
0158     }
0159 
0160     // BUGBUG this is inefficient
0161     typedef typename remove_const<Char>::type char_type;
0162     Char *end = begin + std::char_traits<char_type>::length(begin);
0163     return detail::regex_match_impl(begin, end, what, re, flags);
0164 }
0165 
0166 /// \overload
0167 ///
0168 template<typename BidiRange, typename BidiIter>
0169 inline bool regex_match
0170 (
0171     BidiRange &rng
0172   , match_results<BidiIter> &what
0173   , basic_regex<BidiIter> const &re
0174   , regex_constants::match_flag_type flags = regex_constants::match_default
0175   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0176 )
0177 {
0178     typedef detail::core_access<BidiIter> access;
0179 
0180     if(0 == re.regex_id())
0181     {
0182         access::reset(what);
0183         return false;
0184     }
0185 
0186     // Note that the result iterator of the range must be convertible
0187     // to BidiIter here.
0188     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0189     return detail::regex_match_impl(begin, end, what, re, flags);
0190 }
0191 
0192 /// \overload
0193 ///
0194 template<typename BidiRange, typename BidiIter>
0195 inline bool regex_match
0196 (
0197     BidiRange const &rng
0198   , match_results<BidiIter> &what
0199   , basic_regex<BidiIter> const &re
0200   , regex_constants::match_flag_type flags = regex_constants::match_default
0201   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0202 )
0203 {
0204     typedef detail::core_access<BidiIter> access;
0205 
0206     if(0 == re.regex_id())
0207     {
0208         access::reset(what);
0209         return false;
0210     }
0211 
0212     // Note that the result iterator of the range must be convertible
0213     // to BidiIter here.
0214     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0215     return detail::regex_match_impl(begin, end, what, re, flags);
0216 }
0217 
0218 /// \overload
0219 ///
0220 template<typename Char>
0221 inline bool regex_match
0222 (
0223     BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
0224   , basic_regex<Char *> const &re
0225   , regex_constants::match_flag_type flags = regex_constants::match_default
0226 )
0227 {
0228     if(0 == re.regex_id())
0229     {
0230         return false;
0231     }
0232 
0233     // BUGBUG this is inefficient
0234     match_results<Char *> what;
0235     typedef typename remove_const<Char>::type char_type;
0236     Char *end = begin + std::char_traits<char_type>::length(begin);
0237     return detail::regex_match_impl(begin, end, what, re, flags);
0238 }
0239 
0240 /// \overload
0241 ///
0242 template<typename BidiRange, typename BidiIter>
0243 inline bool regex_match
0244 (
0245     BidiRange &rng
0246   , basic_regex<BidiIter> const &re
0247   , regex_constants::match_flag_type flags = regex_constants::match_default
0248   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0249 )
0250 {
0251     if(0 == re.regex_id())
0252     {
0253         return false;
0254     }
0255 
0256     // BUGBUG this is inefficient
0257     match_results<BidiIter> what;
0258     // Note that the result iterator of the range must be convertible
0259     // to BidiIter here.
0260     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0261     return detail::regex_match_impl(begin, end, what, re, flags);
0262 }
0263 
0264 /// \overload
0265 ///
0266 template<typename BidiRange, typename BidiIter>
0267 inline bool regex_match
0268 (
0269     BidiRange const &rng
0270   , basic_regex<BidiIter> const &re
0271   , regex_constants::match_flag_type flags = regex_constants::match_default
0272   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0273 )
0274 {
0275     if(0 == re.regex_id())
0276     {
0277         return false;
0278     }
0279 
0280     // BUGBUG this is inefficient
0281     match_results<BidiIter> what;
0282     // Note that the result iterator of the range must be convertible
0283     // to BidiIter here.
0284     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0285     return detail::regex_match_impl(begin, end, what, re, flags);
0286 }
0287 
0288 
0289 ///////////////////////////////////////////////////////////////////////////////
0290 // regex_search
0291 ///////////////////////////////////////////////////////////////////////////////
0292 
0293 namespace detail
0294 {
0295     ///////////////////////////////////////////////////////////////////////////////
0296     // regex_search_impl
0297     template<typename BidiIter>
0298     inline bool regex_search_impl
0299     (
0300         match_state<BidiIter> &state
0301       , basic_regex<BidiIter> const &re
0302       , bool not_initial_null = false
0303     )
0304     {
0305         typedef core_access<BidiIter> access;
0306         match_results<BidiIter> &what = *state.context_.results_ptr_;
0307         BOOST_ASSERT(0 != re.regex_id());
0308 
0309         bool const partial_ok = state.flags_.match_partial_;
0310         save_restore<bool> not_null(state.flags_.match_not_null_, state.flags_.match_not_null_ || not_initial_null);
0311         state.flags_.match_prev_avail_ = state.flags_.match_prev_avail_ || !state.bos();
0312 
0313         regex_impl<BidiIter> const &impl = *access::get_regex_impl(re);
0314         BidiIter const begin = state.cur_, end = state.end_;
0315         BidiIter &sub0begin = state.sub_match(0).begin_;
0316         sub0begin = state.cur_;
0317 
0318         // If match_continuous is set, we only need to check for a match at the current position
0319         if(state.flags_.match_continuous_)
0320         {
0321             if(access::match(re, state))
0322             {
0323                 access::set_prefix_suffix(what, begin, end);
0324                 return true;
0325             }
0326 
0327             // handle partial matches
0328             else if(partial_ok && state.found_partial_match_)
0329             {
0330                 state.set_partial_match();
0331                 return true;
0332             }
0333         }
0334 
0335         // If we have a finder, use it to find where a potential match can start
0336         else if(impl.finder_ && (!partial_ok || impl.finder_->ok_for_partial_matches()))
0337         {
0338             finder<BidiIter> const &find = *impl.finder_;
0339             if(find(state))
0340             {
0341                 if(state.cur_ != begin)
0342                 {
0343                     not_null.restore();
0344                 }
0345 
0346                 do
0347                 {
0348                     sub0begin = state.cur_;
0349                     if(access::match(re, state))
0350                     {
0351                         access::set_prefix_suffix(what, begin, end);
0352                         return true;
0353                     }
0354 
0355                     // handle partial matches
0356                     else if(partial_ok && state.found_partial_match_)
0357                     {
0358                         state.set_partial_match();
0359                         return true;
0360                     }
0361 
0362                     BOOST_ASSERT(state.cur_ == sub0begin);
0363                     not_null.restore();
0364                 }
0365                 while(state.cur_ != state.end_ && (++state.cur_, find(state)));
0366             }
0367         }
0368 
0369         // Otherwise, use brute force search at every position.
0370         else
0371         {
0372             for(;;)
0373             {
0374                 if(access::match(re, state))
0375                 {
0376                     access::set_prefix_suffix(what, begin, end);
0377                     return true;
0378                 }
0379 
0380                 // handle partial matches
0381                 else if(partial_ok && state.found_partial_match_)
0382                 {
0383                     state.set_partial_match();
0384                     return true;
0385                 }
0386 
0387                 else if(end == sub0begin)
0388                 {
0389                     break;
0390                 }
0391 
0392                 BOOST_ASSERT(state.cur_ == sub0begin);
0393                 state.cur_ = ++sub0begin;
0394                 not_null.restore();
0395             }
0396         }
0397 
0398         access::reset(what);
0399         return false;
0400     }
0401 } // namespace detail
0402 
0403 
0404 /// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
0405 /// that matches the regular expression \c re.
0406 ///
0407 /// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
0408 /// the regular expression \c re.
0409 ///
0410 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
0411 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
0412 /// \param begin The beginning of the sequence
0413 /// \param end The end of the sequence
0414 /// \param what The \c match_results struct into which the sub_matches will be written
0415 /// \param re The regular expression object to use
0416 /// \param flags Optional match flags, used to control how the expression is matched against
0417 ///        the sequence. (See \c match_flag_type.)
0418 /// \return \c true if a match is found, \c false otherwise
0419 /// \throw regex_error on stack exhaustion
0420 template<typename BidiIter>
0421 inline bool regex_search
0422 (
0423     BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0424   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0425   , match_results<BidiIter> &what
0426   , basic_regex<BidiIter> const &re
0427   , regex_constants::match_flag_type flags = regex_constants::match_default
0428 )
0429 {
0430     typedef detail::core_access<BidiIter> access;
0431 
0432     // a default-constructed regex matches nothing
0433     if(0 == re.regex_id())
0434     {
0435         access::reset(what);
0436         return false;
0437     }
0438 
0439     // the state object holds matching state and
0440     // is passed by reference to all the matchers
0441     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0442     return detail::regex_search_impl(state, re);
0443 }
0444 
0445 /// \overload
0446 ///
0447 template<typename BidiIter>
0448 inline bool regex_search
0449 (
0450     BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0451   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0452   , basic_regex<BidiIter> const &re
0453   , regex_constants::match_flag_type flags = regex_constants::match_default
0454 )
0455 {
0456     typedef detail::core_access<BidiIter> access;
0457 
0458     // a default-constructed regex matches nothing
0459     if(0 == re.regex_id())
0460     {
0461         return false;
0462     }
0463 
0464     // BUGBUG this is inefficient
0465     match_results<BidiIter> what;
0466     // the state object holds matching state and
0467     // is passed by reference to all the matchers
0468     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0469     return detail::regex_search_impl(state, re);
0470 }
0471 
0472 /// \overload
0473 ///
0474 template<typename Char>
0475 inline bool regex_search
0476 (
0477     BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
0478   , match_results<Char *> &what
0479   , basic_regex<Char *> const &re
0480   , regex_constants::match_flag_type flags = regex_constants::match_default
0481 )
0482 {
0483     typedef detail::core_access<Char *> access;
0484 
0485     // a default-constructed regex matches nothing
0486     if(0 == re.regex_id())
0487     {
0488         access::reset(what);
0489         return false;
0490     }
0491 
0492     // BUGBUG this is inefficient
0493     typedef typename remove_const<Char>::type char_type;
0494     Char *end = begin + std::char_traits<char_type>::length(begin);
0495     // the state object holds matching state and
0496     // is passed by reference to all the matchers
0497     detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
0498     return detail::regex_search_impl(state, re);
0499 }
0500 
0501 /// \overload
0502 ///
0503 template<typename BidiRange, typename BidiIter>
0504 inline bool regex_search
0505 (
0506     BidiRange &rng
0507   , match_results<BidiIter> &what
0508   , basic_regex<BidiIter> const &re
0509   , regex_constants::match_flag_type flags = regex_constants::match_default
0510   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0511 )
0512 {
0513     typedef detail::core_access<BidiIter> access;
0514 
0515     // a default-constructed regex matches nothing
0516     if(0 == re.regex_id())
0517     {
0518         access::reset(what);
0519         return false;
0520     }
0521 
0522     // Note that the result iterator of the range must be convertible
0523     // to BidiIter here.
0524     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0525     // the state object holds matching state and
0526     // is passed by reference to all the matchers
0527     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0528     return detail::regex_search_impl(state, re);
0529 }
0530 
0531 /// \overload
0532 ///
0533 template<typename BidiRange, typename BidiIter>
0534 inline bool regex_search
0535 (
0536     BidiRange const &rng
0537   , match_results<BidiIter> &what
0538   , basic_regex<BidiIter> const &re
0539   , regex_constants::match_flag_type flags = regex_constants::match_default
0540   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0541 )
0542 {
0543     typedef detail::core_access<BidiIter> access;
0544 
0545     // a default-constructed regex matches nothing
0546     if(0 == re.regex_id())
0547     {
0548         access::reset(what);
0549         return false;
0550     }
0551 
0552     // Note that the result iterator of the range must be convertible
0553     // to BidiIter here.
0554     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0555     // the state object holds matching state and
0556     // is passed by reference to all the matchers
0557     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0558     return detail::regex_search_impl(state, re);
0559 }
0560 
0561 /// \overload
0562 ///
0563 template<typename Char>
0564 inline bool regex_search
0565 (
0566     BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
0567   , basic_regex<Char *> const &re
0568   , regex_constants::match_flag_type flags = regex_constants::match_default
0569 )
0570 {
0571     typedef detail::core_access<Char *> access;
0572 
0573     // a default-constructed regex matches nothing
0574     if(0 == re.regex_id())
0575     {
0576         return false;
0577     }
0578 
0579     // BUGBUG this is inefficient
0580     match_results<Char *> what;
0581     // BUGBUG this is inefficient
0582     typedef typename remove_const<Char>::type char_type;
0583     Char *end = begin + std::char_traits<char_type>::length(begin);
0584     // the state object holds matching state and
0585     // is passed by reference to all the matchers
0586     detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
0587     return detail::regex_search_impl(state, re);
0588 }
0589 
0590 /// \overload
0591 ///
0592 template<typename BidiRange, typename BidiIter>
0593 inline bool regex_search
0594 (
0595     BidiRange &rng
0596   , basic_regex<BidiIter> const &re
0597   , regex_constants::match_flag_type flags = regex_constants::match_default
0598   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0599 )
0600 {
0601     typedef detail::core_access<BidiIter> access;
0602 
0603     // a default-constructed regex matches nothing
0604     if(0 == re.regex_id())
0605     {
0606         return false;
0607     }
0608 
0609     // BUGBUG this is inefficient
0610     match_results<BidiIter> what;
0611     // Note that the result iterator of the range must be convertible
0612     // to BidiIter here.
0613     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0614     // the state object holds matching state and
0615     // is passed by reference to all the matchers
0616     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0617     return detail::regex_search_impl(state, re);
0618 }
0619 
0620 /// \overload
0621 ///
0622 template<typename BidiRange, typename BidiIter>
0623 inline bool regex_search
0624 (
0625     BidiRange const &rng
0626   , basic_regex<BidiIter> const &re
0627   , regex_constants::match_flag_type flags = regex_constants::match_default
0628   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
0629 )
0630 {
0631     typedef detail::core_access<BidiIter> access;
0632 
0633     // a default-constructed regex matches nothing
0634     if(0 == re.regex_id())
0635     {
0636         return false;
0637     }
0638 
0639     // BUGBUG this is inefficient
0640     match_results<BidiIter> what;
0641     // Note that the result iterator of the range must be convertible
0642     // to BidiIter here.
0643     BidiIter begin = boost::begin(rng), end = boost::end(rng);
0644     // the state object holds matching state and
0645     // is passed by reference to all the matchers
0646     detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0647     return detail::regex_search_impl(state, re);
0648 }
0649 
0650 
0651 ///////////////////////////////////////////////////////////////////////////////
0652 // regex_replace
0653 ///////////////////////////////////////////////////////////////////////////////
0654 
0655 namespace detail
0656 {
0657     ///////////////////////////////////////////////////////////////////////////////
0658     // regex_replace_impl
0659     template<typename OutIter, typename BidiIter, typename Formatter>
0660     inline OutIter regex_replace_impl
0661     (
0662         OutIter out
0663       , BidiIter begin
0664       , BidiIter end
0665       , basic_regex<BidiIter> const &re
0666       , Formatter const &format
0667       , regex_constants::match_flag_type flags = regex_constants::match_default
0668     )
0669     {
0670         using namespace regex_constants;
0671         typedef detail::core_access<BidiIter> access;
0672         BOOST_ASSERT(0 != re.regex_id());
0673 
0674         BidiIter cur = begin;
0675         match_results<BidiIter> what;
0676         detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
0677         bool const yes_copy = (0 == (flags & format_no_copy));
0678 
0679         if(detail::regex_search_impl(state, re))
0680         {
0681             if(yes_copy)
0682             {
0683                 out = std::copy(cur, what[0].first, out);
0684             }
0685 
0686             out = what.format(out, format, flags);
0687             cur = state.cur_ = state.next_search_ = what[0].second;
0688 
0689             if(0 == (flags & format_first_only))
0690             {
0691                 bool not_null = (0 == what.length());
0692                 state.reset(what, *access::get_regex_impl(re));
0693                 while(detail::regex_search_impl(state, re, not_null))
0694                 {
0695                     if(yes_copy)
0696                     {
0697                         out = std::copy(cur, what[0].first, out);
0698                     }
0699 
0700                     access::set_prefix_suffix(what, begin, end);
0701                     out = what.format(out, format, flags);
0702                     cur = state.cur_ = state.next_search_ = what[0].second;
0703                     not_null = (0 == what.length());
0704                     state.reset(what, *access::get_regex_impl(re));
0705                 }
0706             }
0707         }
0708 
0709         if(yes_copy)
0710         {
0711             out = std::copy(cur, end, out);
0712         }
0713 
0714         return out;
0715     }
0716 } // namespace detail
0717 
0718 /// \brief Build an output sequence given an input sequence, a regex, and a format string or
0719 /// a formatter object, function, or expression.
0720 ///
0721 /// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
0722 /// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
0723 /// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
0724 /// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
0725 /// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
0726 /// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
0727 /// where \c last_m is a copy of the last match found.
0728 ///
0729 /// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
0730 ///
0731 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
0732 /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
0733 /// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
0734 ///      <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
0735 ///      <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
0736 ///      or else it is a null-terminated format string, or an expression template
0737 ///      representing a formatter lambda expression.
0738 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
0739 /// \param out An output iterator into which the output sequence is written.
0740 /// \param begin The beginning of the input sequence.
0741 /// \param end The end of the input sequence.
0742 /// \param re The regular expression object to use.
0743 /// \param format The format string used to format the replacement sequence,
0744 ///        or a formatter function, function object, or expression.
0745 /// \param flags Optional match flags, used to control how the expression is matched against
0746 ///        the sequence. (See \c match_flag_type.)
0747 /// \return The value of the output iterator after the output sequence has been written to it.
0748 /// \throw regex_error on stack exhaustion or invalid format string.
0749 template<typename OutIter, typename BidiIter, typename Formatter>
0750 inline OutIter regex_replace
0751 (
0752     OutIter out
0753   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0754   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0755   , basic_regex<BidiIter> const &re
0756   , Formatter const &format
0757   , regex_constants::match_flag_type flags = regex_constants::match_default
0758   , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
0759 )
0760 {
0761     // Default-constructed regexes match nothing
0762     if(0 == re.regex_id())
0763     {
0764         if((0 == (flags & regex_constants::format_no_copy)))
0765         {
0766             out = std::copy(begin, end, out);
0767         }
0768 
0769         return out;
0770     }
0771 
0772     return detail::regex_replace_impl(out, begin, end, re, format, flags);
0773 }
0774 
0775 /// \overload
0776 ///
0777 template<typename OutIter, typename BidiIter>
0778 inline OutIter regex_replace
0779 (
0780     OutIter out
0781   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
0782   , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
0783   , basic_regex<BidiIter> const &re
0784   , typename iterator_value<BidiIter>::type const *format
0785   , regex_constants::match_flag_type flags = regex_constants::match_default
0786 )
0787 {
0788     // Default-constructed regexes match nothing
0789     if(0 == re.regex_id())
0790     {
0791         if((0 == (flags & regex_constants::format_no_copy)))
0792         {
0793             out = std::copy(begin, end, out);
0794         }
0795 
0796         return out;
0797     }
0798 
0799     return detail::regex_replace_impl(out, begin, end, re, format, flags);
0800 }
0801 
0802 /// \overload
0803 ///
0804 template<typename BidiContainer, typename BidiIter, typename Formatter>
0805 inline BidiContainer regex_replace
0806 (
0807     BidiContainer &str
0808   , basic_regex<BidiIter> const &re
0809   , Formatter const &format
0810   , regex_constants::match_flag_type flags = regex_constants::match_default
0811   , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
0812 )
0813 {
0814     BidiContainer result;
0815     // Note that the result iterator of the range must be convertible
0816     // to BidiIter here.
0817     BidiIter begin = boost::begin(str), end = boost::end(str);
0818 
0819     // Default-constructed regexes match nothing
0820     if(0 == re.regex_id())
0821     {
0822         if((0 == (flags & regex_constants::format_no_copy)))
0823         {
0824             std::copy(begin, end, std::back_inserter(result));
0825         }
0826 
0827         return result;
0828     }
0829 
0830     detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
0831     return result;
0832 }
0833 
0834 /// \overload
0835 ///
0836 template<typename BidiContainer, typename BidiIter, typename Formatter>
0837 inline BidiContainer regex_replace
0838 (
0839     BidiContainer const &str
0840   , basic_regex<BidiIter> const &re
0841   , Formatter const &format
0842   , regex_constants::match_flag_type flags = regex_constants::match_default
0843   , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
0844 )
0845 {
0846     BidiContainer result;
0847     // Note that the result iterator of the range must be convertible
0848     // to BidiIter here.
0849     BidiIter begin = boost::begin(str), end = boost::end(str);
0850 
0851     // Default-constructed regexes match nothing
0852     if(0 == re.regex_id())
0853     {
0854         if((0 == (flags & regex_constants::format_no_copy)))
0855         {
0856             std::copy(begin, end, std::back_inserter(result));
0857         }
0858 
0859         return result;
0860     }
0861 
0862     detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
0863     return result;
0864 }
0865 
0866 /// \overload
0867 ///
0868 template<typename Char, typename Formatter>
0869 inline std::basic_string<typename remove_const<Char>::type> regex_replace
0870 (
0871     BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
0872   , basic_regex<Char *> const &re
0873   , Formatter const &format
0874   , regex_constants::match_flag_type flags = regex_constants::match_default
0875   , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
0876 )
0877 {
0878     typedef typename remove_const<Char>::type char_type;
0879     std::basic_string<char_type> result;
0880 
0881     // Default-constructed regexes match nothing
0882     if(0 == re.regex_id())
0883     {
0884         if((0 == (flags & regex_constants::format_no_copy)))
0885         {
0886             result = str;
0887         }
0888 
0889         return result;
0890     }
0891 
0892     Char *end = str + std::char_traits<char_type>::length(str);
0893     detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
0894     return result;
0895 }
0896 
0897 /// \overload
0898 ///
0899 template<typename BidiContainer, typename BidiIter>
0900 inline BidiContainer regex_replace
0901 (
0902     BidiContainer &str
0903   , basic_regex<BidiIter> const &re
0904   , typename iterator_value<BidiIter>::type const *format
0905   , regex_constants::match_flag_type flags = regex_constants::match_default
0906   , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
0907 )
0908 {
0909     BidiContainer result;
0910     // Note that the result iterator of the range must be convertible
0911     // to BidiIter here.
0912     BidiIter begin = boost::begin(str), end = boost::end(str);
0913 
0914     // Default-constructed regexes match nothing
0915     if(0 == re.regex_id())
0916     {
0917         if((0 == (flags & regex_constants::format_no_copy)))
0918         {
0919             std::copy(begin, end, std::back_inserter(result));
0920         }
0921 
0922         return result;
0923     }
0924 
0925     detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
0926     return result;
0927 }
0928 
0929 /// \overload
0930 ///
0931 template<typename BidiContainer, typename BidiIter>
0932 inline BidiContainer regex_replace
0933 (
0934     BidiContainer const &str
0935   , basic_regex<BidiIter> const &re
0936   , typename iterator_value<BidiIter>::type const *format
0937   , regex_constants::match_flag_type flags = regex_constants::match_default
0938   , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
0939 )
0940 {
0941     BidiContainer result;
0942     // Note that the result iterator of the range must be convertible
0943     // to BidiIter here.
0944     BidiIter begin = boost::begin(str), end = boost::end(str);
0945 
0946     // Default-constructed regexes match nothing
0947     if(0 == re.regex_id())
0948     {
0949         if((0 == (flags & regex_constants::format_no_copy)))
0950         {
0951             std::copy(begin, end, std::back_inserter(result));
0952         }
0953 
0954         return result;
0955     }
0956 
0957     detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
0958     return result;
0959 }
0960 
0961 /// \overload
0962 ///
0963 template<typename Char>
0964 inline std::basic_string<typename remove_const<Char>::type> regex_replace
0965 (
0966     BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
0967   , basic_regex<Char *> const &re
0968   , typename add_const<Char>::type *format
0969   , regex_constants::match_flag_type flags = regex_constants::match_default
0970 )
0971 {
0972     typedef typename remove_const<Char>::type char_type;
0973     std::basic_string<char_type> result;
0974 
0975     // Default-constructed regexes match nothing
0976     if(0 == re.regex_id())
0977     {
0978         if((0 == (flags & regex_constants::format_no_copy)))
0979         {
0980             result = str;
0981         }
0982 
0983         return result;
0984     }
0985 
0986     Char *end = str + std::char_traits<char_type>::length(str);
0987     detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
0988     return result;
0989 }
0990 
0991 }} // namespace boost::xpressive
0992 
0993 #endif