|
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