Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49854 - in trunk/boost/xpressive: . detail/core
From: eric_at_[hidden]
Date: 2008-11-20 16:49:38


Author: eric_niebler
Date: 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
New Revision: 49854
URL: http://svn.boost.org/trac/boost/changeset/49854

Log:
optimize algorithms and iterators for the regex_id()==0 case
Text files modified:
   trunk/boost/xpressive/basic_regex.hpp | 32 ++
   trunk/boost/xpressive/detail/core/access.hpp | 5
   trunk/boost/xpressive/regex_algorithms.hpp | 488 ++++++++++++++++++++++++++++++---------
   trunk/boost/xpressive/regex_iterator.hpp | 18 +
   trunk/boost/xpressive/regex_token_iterator.hpp | 36 ++
   5 files changed, 436 insertions(+), 143 deletions(-)

Modified: trunk/boost/xpressive/basic_regex.hpp
==============================================================================
--- trunk/boost/xpressive/basic_regex.hpp (original)
+++ trunk/boost/xpressive/basic_regex.hpp 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
@@ -15,6 +15,7 @@
 # pragma once
 #endif
 
+#include <boost/config.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/xpressive/xpressive_fwd.hpp>
 #include <boost/xpressive/regex_constants.hpp>
@@ -61,9 +62,21 @@
 public:
     typedef BidiIter iterator_type;
     typedef typename iterator_value<BidiIter>::type char_type;
+ // For compatibility with std::basic_regex
+ typedef typename iterator_value<BidiIter>::type value_type;
     typedef typename detail::string_type<char_type>::type string_type;
     typedef regex_constants::syntax_option_type flag_type;
 
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ECMAScript = regex_constants::ECMAScript);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, icase = regex_constants::icase_);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, nosubs = regex_constants::nosubs);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, optimize = regex_constants::optimize);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, collate = regex_constants::collate);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, single_line = regex_constants::single_line);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_null = regex_constants::not_dot_null);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_newline = regex_constants::not_dot_newline);
+ BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ignore_white_space = regex_constants::ignore_white_space);
+
     /// \post regex_id() == 0
     /// \post mark_count() == 0
     basic_regex()
@@ -229,13 +242,6 @@
         #endif
     }
 
- // Returns true if this basic_regex object does not contain a valid regular expression.
- /// INTERNAL ONLY
- bool invalid_() const
- {
- return !proto::value(*this) || !proto::value(*this)->xpr_;
- }
-
     // Compiles valid static regexes into a state machine.
     /// INTERNAL ONLY
     template<typename Expr>
@@ -255,6 +261,18 @@
     void dump_(std::ostream &sout) const;
 };
 
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ECMAScript;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::icase;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::nosubs;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::optimize;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::collate;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::single_line;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_null;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_newline;
+template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ignore_white_space;
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 // swap
 /// \brief Swaps the contents of two basic_regex objects.

Modified: trunk/boost/xpressive/detail/core/access.hpp
==============================================================================
--- trunk/boost/xpressive/detail/core/access.hpp (original)
+++ trunk/boost/xpressive/detail/core/access.hpp 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
@@ -35,11 +35,6 @@
         return proto::value(rex)->hidden_mark_count_;
     }
 
- static bool invalid(basic_regex<BidiIter> const &rex)
- {
- return rex.invalid_();
- }
-
     static bool match(basic_regex<BidiIter> const &rex, match_state<BidiIter> &state)
     {
         return rex.match_(state);

Modified: trunk/boost/xpressive/regex_algorithms.hpp
==============================================================================
--- trunk/boost/xpressive/regex_algorithms.hpp (original)
+++ trunk/boost/xpressive/regex_algorithms.hpp 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
@@ -40,6 +40,47 @@
 // regex_match
 ///////////////////////////////////////////////////////////////////////////////
 
+namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////////
+ // regex_match_impl
+ template<typename BidiIter>
+ inline bool regex_match_impl
+ (
+ BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
+ , match_results<BidiIter> &what
+ , basic_regex<BidiIter> const &re
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ )
+ {
+ typedef detail::core_access<BidiIter> access;
+ BOOST_ASSERT(0 != re.regex_id());
+
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ state.flags_.match_all_ = true;
+ state.sub_match(0).begin_ = begin;
+
+ if(access::match(re, state))
+ {
+ access::set_prefix_suffix(what, begin, end);
+ return true;
+ }
+
+ // handle partial matches
+ else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
+ {
+ state.set_partial_match();
+ return true;
+ }
+
+ access::reset(what);
+ return false;
+ }
+} // namespace detail
+
 /// \brief See if a regex matches a sequence from beginning to end.
 ///
 /// Determines whether there is an exact match between the regular expression \c re,
@@ -67,31 +108,13 @@
 {
     typedef detail::core_access<BidiIter> access;
 
- // an invlid regex matches nothing
- if(!access::invalid(re))
+ if(0 == re.regex_id())
     {
- // the state object holds matching state and
- // is passed by reference to all the matchers
- detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
- state.flags_.match_all_ = true;
- state.sub_match(0).begin_ = begin;
-
- if(access::match(re, state))
- {
- access::set_prefix_suffix(what, begin, end);
- return true;
- }
-
- // handle partial matches
- else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
- {
- state.set_partial_match();
- return true;
- }
+ access::reset(what);
+ return false;
     }
 
- access::reset(what);
- return false;
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -105,9 +128,14 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_match(begin, end, what, re, flags);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -121,10 +149,18 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ typedef detail::core_access<Char *> access;
+
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // BUGBUG this is inefficient
     typedef typename remove_const<Char>::type char_type;
     Char *end = begin + std::char_traits<char_type>::length(begin);
- return xpressive::regex_match(begin, end, what, re, flags);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -139,10 +175,18 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return xpressive::regex_match(begin, end, what, re, flags);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -157,10 +201,18 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return xpressive::regex_match(begin, end, what, re, flags);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -173,9 +225,16 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<Char *> what;
- return xpressive::regex_match(begin, what, re, flags);
+ typedef typename remove_const<Char>::type char_type;
+ Char *end = begin + std::char_traits<char_type>::length(begin);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -189,9 +248,17 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_match(rng, what, re, flags);
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(rng), end = boost::end(rng);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -205,9 +272,17 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_match(rng, what, re, flags);
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(rng), end = boost::end(rng);
+ return detail::regex_match_impl(begin, end, what, re, flags);
 }
 
 
@@ -217,23 +292,21 @@
 
 namespace detail
 {
-///////////////////////////////////////////////////////////////////////////////
-// regex_search_impl
-template<typename BidiIter>
-inline bool regex_search_impl
-(
- match_state<BidiIter> &state
- , basic_regex<BidiIter> const &re
- , bool not_initial_null = false
-)
-{
- typedef core_access<BidiIter> access;
- typedef typename iterator_value<BidiIter>::type char_type;
- match_results<BidiIter> &what = *state.context_.results_ptr_;
-
- // an invlid regex matches nothing
- if(!access::invalid(re))
+ ///////////////////////////////////////////////////////////////////////////////
+ // regex_search_impl
+ template<typename BidiIter>
+ inline bool regex_search_impl
+ (
+ match_state<BidiIter> &state
+ , basic_regex<BidiIter> const &re
+ , bool not_initial_null = false
+ )
     {
+ typedef core_access<BidiIter> access;
+ typedef typename iterator_value<BidiIter>::type char_type;
+ match_results<BidiIter> &what = *state.context_.results_ptr_;
+ BOOST_ASSERT(0 != re.regex_id());
+
         bool const partial_ok = state.flags_.match_partial_;
         save_restore<bool> not_null(state.flags_.match_not_null_, state.flags_.match_not_null_ || not_initial_null);
         state.flags_.match_prev_avail_ = state.flags_.match_prev_avail_ || !state.bos();
@@ -322,11 +395,10 @@
                 not_null.restore();
             }
         }
- }
 
- access::reset(what);
- return false;
-}
+ access::reset(what);
+ return false;
+ }
 } // namespace detail
 
 
@@ -358,17 +430,17 @@
 {
     typedef detail::core_access<BidiIter> access;
 
- // an invlid regex matches nothing
- if(!access::invalid(re))
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
     {
- // the state object holds matching state and
- // is passed by reference to all the matchers
- detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
- return detail::regex_search_impl(state, re);
+ access::reset(what);
+ return false;
     }
 
- access::reset(what);
- return false;
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -382,9 +454,20 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_search(begin, end, what, re, flags);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -398,10 +481,22 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ typedef detail::core_access<Char *> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // BUGBUG this is inefficient
     typedef typename remove_const<Char>::type char_type;
     Char *end = begin + std::char_traits<char_type>::length(begin);
- return xpressive::regex_search(begin, end, what, re, flags);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -416,10 +511,22 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return xpressive::regex_search(begin, end, what, re, flags);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -434,10 +541,22 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ access::reset(what);
+ return false;
+ }
+
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return xpressive::regex_search(begin, end, what, re, flags);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -450,9 +569,23 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ typedef detail::core_access<Char *> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<Char *> what;
- return xpressive::regex_search(begin, what, re, flags);
+ // BUGBUG this is inefficient
+ typedef typename remove_const<Char>::type char_type;
+ Char *end = begin + std::char_traits<char_type>::length(begin);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -466,9 +599,23 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_search(rng, what, re, flags);
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(rng), end = boost::end(rng);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 /// \overload
@@ -482,9 +629,23 @@
   , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
+ typedef detail::core_access<BidiIter> access;
+
+ // a default-constructed regex matches nothing
+ if(0 == re.regex_id())
+ {
+ return false;
+ }
+
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return xpressive::regex_search(rng, what, re, flags);
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(rng), end = boost::end(rng);
+ // the state object holds matching state and
+ // is passed by reference to all the matchers
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ return detail::regex_search_impl(state, re);
 }
 
 
@@ -494,64 +655,65 @@
 
 namespace detail
 {
-///////////////////////////////////////////////////////////////////////////////
-// regex_replace_impl
-template<typename OutIter, typename BidiIter, typename Formatter>
-inline OutIter regex_replace_impl
-(
- OutIter out
- , BidiIter begin
- , BidiIter end
- , basic_regex<BidiIter> const &re
- , Formatter const &format
- , regex_constants::match_flag_type flags = regex_constants::match_default
-)
-{
- using namespace regex_constants;
- typedef detail::core_access<BidiIter> access;
+ ///////////////////////////////////////////////////////////////////////////////
+ // regex_replace_impl
+ template<typename OutIter, typename BidiIter, typename Formatter>
+ inline OutIter regex_replace_impl
+ (
+ OutIter out
+ , BidiIter begin
+ , BidiIter end
+ , basic_regex<BidiIter> const &re
+ , Formatter const &format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ )
+ {
+ using namespace regex_constants;
+ typedef detail::core_access<BidiIter> access;
+ BOOST_ASSERT(0 != re.regex_id());
 
- BidiIter cur = begin;
- match_results<BidiIter> what;
- detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
- bool const yes_copy = (0 == (flags & format_no_copy));
+ BidiIter cur = begin;
+ match_results<BidiIter> what;
+ detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
+ bool const yes_copy = (0 == (flags & format_no_copy));
 
- if(detail::regex_search_impl(state, re))
- {
- if(yes_copy)
+ if(detail::regex_search_impl(state, re))
         {
- out = std::copy(cur, what[0].first, out);
- }
+ if(yes_copy)
+ {
+ out = std::copy(cur, what[0].first, out);
+ }
 
- out = what.format(out, format, flags);
- cur = state.cur_ = state.next_search_ = what[0].second;
+ out = what.format(out, format, flags);
+ cur = state.cur_ = state.next_search_ = what[0].second;
 
- if(0 == (flags & format_first_only))
- {
- bool not_null = (0 == what.length());
- state.reset(what, *access::get_regex_impl(re));
- while(detail::regex_search_impl(state, re, not_null))
+ if(0 == (flags & format_first_only))
             {
- if(yes_copy)
+ bool not_null = (0 == what.length());
+ state.reset(what, *access::get_regex_impl(re));
+ while(detail::regex_search_impl(state, re, not_null))
                 {
- out = std::copy(cur, what[0].first, out);
- }
+ if(yes_copy)
+ {
+ out = std::copy(cur, what[0].first, out);
+ }
 
- access::set_prefix_suffix(what, begin, end);
- out = what.format(out, format, flags);
- cur = state.cur_ = state.next_search_ = what[0].second;
- not_null = (0 == what.length());
- state.reset(what, *access::get_regex_impl(re));
+ access::set_prefix_suffix(what, begin, end);
+ out = what.format(out, format, flags);
+ cur = state.cur_ = state.next_search_ = what[0].second;
+ not_null = (0 == what.length());
+ state.reset(what, *access::get_regex_impl(re));
+ }
             }
         }
- }
 
- if(yes_copy)
- {
- out = std::copy(cur, end, out);
- }
+ if(yes_copy)
+ {
+ out = std::copy(cur, end, out);
+ }
 
- return out;
-}
+ return out;
+ }
 } // namespace detail
 
 /// \brief Build an output sequence given an input sequence, a regex, and a format string or
@@ -597,6 +759,17 @@
   , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
 )
 {
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ out = std::copy(begin, end, out);
+ }
+
+ return out;
+ }
+
     return detail::regex_replace_impl(out, begin, end, re, format, flags);
 }
 
@@ -613,6 +786,17 @@
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ out = std::copy(begin, end, out);
+ }
+
+ return out;
+ }
+
     return detail::regex_replace_impl(out, begin, end, re, format, flags);
 }
 
@@ -632,7 +816,19 @@
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(str), end = boost::end(str);
- xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ std::copy(begin, end, std::back_inserter(result));
+ }
+
+ return result;
+ }
+
+ detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
     return result;
 }
 
@@ -652,7 +848,19 @@
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(str), end = boost::end(str);
- xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ std::copy(begin, end, std::back_inserter(result));
+ }
+
+ return result;
+ }
+
+ detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
     return result;
 }
 
@@ -670,8 +878,20 @@
 {
     typedef typename remove_const<Char>::type char_type;
     std::basic_string<char_type> result;
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ result = str;
+ }
+
+ return result;
+ }
+
     Char *end = str + std::char_traits<char_type>::length(str);
- xpressive::regex_replace(std::back_inserter(result), str, end, re, format, flags);
+ detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
     return result;
 }
 
@@ -691,7 +911,19 @@
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(str), end = boost::end(str);
- xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ std::copy(begin, end, std::back_inserter(result));
+ }
+
+ return result;
+ }
+
+ detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
     return result;
 }
 
@@ -711,7 +943,19 @@
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(str), end = boost::end(str);
- xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ std::copy(begin, end, std::back_inserter(result));
+ }
+
+ return result;
+ }
+
+ detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
     return result;
 }
 
@@ -728,8 +972,20 @@
 {
     typedef typename remove_const<Char>::type char_type;
     std::basic_string<char_type> result;
+
+ // Default-constructed regexes match nothing
+ if(0 == re.regex_id())
+ {
+ if((0 == (flags & regex_constants::format_no_copy)))
+ {
+ result = str;
+ }
+
+ return result;
+ }
+
     Char *end = str + std::char_traits<char_type>::length(str);
- xpressive::regex_replace(std::back_inserter(result), str, end, re, format, flags);
+ detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
     return result;
 }
 

Modified: trunk/boost/xpressive/regex_iterator.hpp
==============================================================================
--- trunk/boost/xpressive/regex_iterator.hpp (original)
+++ trunk/boost/xpressive/regex_iterator.hpp 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
@@ -118,9 +118,13 @@
       , basic_regex<BidiIter> const &rex
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex, flags))
+ : impl_()
     {
- this->next_();
+ if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
+ this->next_();
+ }
     }
 
     template<typename LetExpr>
@@ -132,10 +136,14 @@
       , detail::let_<LetExpr> const &args
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex, flags))
+ : impl_()
     {
- detail::bind_args(args, this->impl_->what_);
- this->next_();
+ if(0 != rex.regex_id()) // Empty regexes are guaranteed to match nothing
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags);
+ detail::bind_args(args, this->impl_->what_);
+ this->next_();
+ }
     }
 
     regex_iterator(regex_iterator<BidiIter> const &that)

Modified: trunk/boost/xpressive/regex_token_iterator.hpp
==============================================================================
--- trunk/boost/xpressive/regex_token_iterator.hpp (original)
+++ trunk/boost/xpressive/regex_token_iterator.hpp 2008-11-20 16:49:37 EST (Thu, 20 Nov 2008)
@@ -159,9 +159,13 @@
       , BidiIter end
       , basic_regex<BidiIter> const &rex
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex))
+ : impl_()
     {
- this->next_();
+ if(0 != rex.regex_id())
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex);
+ this->next_();
+ }
     }
 
     /// \param begin The beginning of the character range to search.
@@ -177,10 +181,14 @@
       , basic_regex<BidiIter> const &rex
       , detail::let_<LetExpr> const &args
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex))
+ : impl_()
     {
- detail::bind_args(args, this->impl_->iter_.what_);
- this->next_();
+ if(0 != rex.regex_id())
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex);
+ detail::bind_args(args, this->impl_->iter_.what_);
+ this->next_();
+ }
     }
 
     /// \param begin The beginning of the character range to search.
@@ -199,9 +207,13 @@
       , Subs const &subs
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex, flags, detail::to_vector(subs)))
+ : impl_()
     {
- this->next_();
+ if(0 != rex.regex_id())
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags, detail::to_vector(subs));
+ this->next_();
+ }
     }
 
     /// \param begin The beginning of the character range to search.
@@ -222,10 +234,14 @@
       , detail::let_<LetExpr> const &args
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, begin, rex, flags, detail::to_vector(subs)))
+ : impl_()
     {
- detail::bind_args(args, this->impl_->iter_.what_);
- this->next_();
+ if(0 != rex.regex_id())
+ {
+ this->impl_ = new impl_type_(begin, begin, end, begin, rex, flags, detail::to_vector(subs));
+ detail::bind_args(args, this->impl_->iter_.what_);
+ this->next_();
+ }
     }
 
     /// \post <tt>*this == that</tt>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk