$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49881 - in branches/release: . boost/xpressive boost/xpressive/detail/core
From: eric_at_[hidden]
Date: 2008-11-22 20:39:52
Author: eric_niebler
Date: 2008-11-22 20:39:51 EST (Sat, 22 Nov 2008)
New Revision: 49881
URL: http://svn.boost.org/trac/boost/changeset/49881
Log:
Merged revisions 49854 via svnmerge from 
https://svn.boost.org/svn/boost/trunk
........
  r49854 | eric_niebler | 2008-11-20 13:49:37 -0800 (Thu, 20 Nov 2008) | 1 line
  
  optimize algorithms and iterators for the regex_id()==0 case
........
Properties modified: 
   branches/release/   (props changed)
Text files modified: 
   branches/release/boost/xpressive/basic_regex.hpp          |    32 ++                                      
   branches/release/boost/xpressive/detail/core/access.hpp   |     5                                         
   branches/release/boost/xpressive/regex_algorithms.hpp     |   488 ++++++++++++++++++++++++++++++--------- 
   branches/release/boost/xpressive/regex_iterator.hpp       |    18 +                                       
   branches/release/boost/xpressive/regex_token_iterator.hpp |    36 ++                                      
   5 files changed, 436 insertions(+), 143 deletions(-)
Modified: branches/release/boost/xpressive/basic_regex.hpp
==============================================================================
--- branches/release/boost/xpressive/basic_regex.hpp	(original)
+++ branches/release/boost/xpressive/basic_regex.hpp	2008-11-22 20:39:51 EST (Sat, 22 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: branches/release/boost/xpressive/detail/core/access.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/access.hpp	(original)
+++ branches/release/boost/xpressive/detail/core/access.hpp	2008-11-22 20:39:51 EST (Sat, 22 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: branches/release/boost/xpressive/regex_algorithms.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_algorithms.hpp	(original)
+++ branches/release/boost/xpressive/regex_algorithms.hpp	2008-11-22 20:39:51 EST (Sat, 22 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: branches/release/boost/xpressive/regex_iterator.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_iterator.hpp	(original)
+++ branches/release/boost/xpressive/regex_iterator.hpp	2008-11-22 20:39:51 EST (Sat, 22 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: branches/release/boost/xpressive/regex_token_iterator.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_token_iterator.hpp	(original)
+++ branches/release/boost/xpressive/regex_token_iterator.hpp	2008-11-22 20:39:51 EST (Sat, 22 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>