Minor optimizations. Minor bug fixes. More tests.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@108331 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
173968a5f2
commit
68025ed084
@ -2040,6 +2040,7 @@ class __bracket_expression
|
|||||||
bool __negate_;
|
bool __negate_;
|
||||||
bool __icase_;
|
bool __icase_;
|
||||||
bool __collate_;
|
bool __collate_;
|
||||||
|
bool __might_have_digraph_;
|
||||||
|
|
||||||
__bracket_expression(const __bracket_expression&);
|
__bracket_expression(const __bracket_expression&);
|
||||||
__bracket_expression& operator=(const __bracket_expression&);
|
__bracket_expression& operator=(const __bracket_expression&);
|
||||||
@ -2049,7 +2050,8 @@ public:
|
|||||||
__bracket_expression(const _Traits& __traits, __node<_CharT>* __s,
|
__bracket_expression(const _Traits& __traits, __node<_CharT>* __s,
|
||||||
bool __negate, bool __icase, bool __collate)
|
bool __negate, bool __icase, bool __collate)
|
||||||
: base(__s), __traits_(__traits), __mask_(), __negate_(__negate),
|
: base(__s), __traits_(__traits), __mask_(), __negate_(__negate),
|
||||||
__icase_(__icase), __collate_(__collate) {}
|
__icase_(__icase), __collate_(__collate),
|
||||||
|
__might_have_digraph_(__traits_.getloc().name() != "C") {}
|
||||||
|
|
||||||
virtual void __exec(__state&) const;
|
virtual void __exec(__state&) const;
|
||||||
|
|
||||||
@ -2129,6 +2131,8 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
|
|||||||
if (__s.__current_ != __s.__last_)
|
if (__s.__current_ != __s.__last_)
|
||||||
{
|
{
|
||||||
++__consumed;
|
++__consumed;
|
||||||
|
if (__might_have_digraph_)
|
||||||
|
{
|
||||||
const _CharT* __next = next(__s.__current_);
|
const _CharT* __next = next(__s.__current_);
|
||||||
if (__next != __s.__last_)
|
if (__next != __s.__last_)
|
||||||
{
|
{
|
||||||
@ -2191,6 +2195,7 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// test *__s.__current_ as not a digraph
|
// test *__s.__current_ as not a digraph
|
||||||
_CharT __ch = *__s.__current_;
|
_CharT __ch = *__s.__current_;
|
||||||
if (__icase_)
|
if (__icase_)
|
||||||
@ -3405,18 +3410,25 @@ template <class _CharT, class _Traits>
|
|||||||
void
|
void
|
||||||
basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()
|
basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()
|
||||||
{
|
{
|
||||||
__end_->first() = new __begin_marked_subexpression<_CharT>(++__marked_count_,
|
if (!(__flags_ & nosubs))
|
||||||
|
{
|
||||||
|
__end_->first() =
|
||||||
|
new __begin_marked_subexpression<_CharT>(++__marked_count_,
|
||||||
__end_->first());
|
__end_->first());
|
||||||
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Traits>
|
template <class _CharT, class _Traits>
|
||||||
void
|
void
|
||||||
basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)
|
basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)
|
||||||
{
|
{
|
||||||
__end_->first() = new __end_marked_subexpression<_CharT>(__sub,
|
if (!(__flags_ & nosubs))
|
||||||
__end_->first());
|
{
|
||||||
|
__end_->first() =
|
||||||
|
new __end_marked_subexpression<_CharT>(__sub, __end_->first());
|
||||||
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Traits>
|
template <class _CharT, class _Traits>
|
||||||
@ -4045,14 +4057,11 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
|
|||||||
{
|
{
|
||||||
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
||||||
deque<__state> __states;
|
deque<__state> __states;
|
||||||
difference_type __j = 0;
|
|
||||||
difference_type __highest_j = 0;
|
difference_type __highest_j = 0;
|
||||||
difference_type _N = _STD::distance(__first, __last);
|
difference_type _N = _STD::distance(__first, __last);
|
||||||
__node* __st = __start_.get();
|
__node* __st = __start_.get();
|
||||||
if (__st)
|
if (__st)
|
||||||
{
|
{
|
||||||
__states.push_back(__state());
|
|
||||||
__states.back().__do_ = __state::__consume_input;
|
|
||||||
__states.push_back(__state());
|
__states.push_back(__state());
|
||||||
__states.back().__do_ = 0;
|
__states.back().__do_ = 0;
|
||||||
__states.back().__first_ = __first;
|
__states.back().__first_ = __first;
|
||||||
@ -4061,7 +4070,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
|
|||||||
__states.back().__loop_data_.resize(__loop_count());
|
__states.back().__loop_data_.resize(__loop_count());
|
||||||
__states.back().__node_ = __st;
|
__states.back().__node_ = __st;
|
||||||
__states.back().__flags_ = __flags;
|
__states.back().__flags_ = __flags;
|
||||||
_BidirectionalIterator __current = __first;
|
bool __matched = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
__state& __s = __states.back();
|
__state& __s = __states.back();
|
||||||
@ -4070,25 +4079,19 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
|
|||||||
switch (__s.__do_)
|
switch (__s.__do_)
|
||||||
{
|
{
|
||||||
case __state::__end_state:
|
case __state::__end_state:
|
||||||
__highest_j = _STD::max(__highest_j, __j);
|
if (__highest_j < __s.__current_ - __s.__first_)
|
||||||
|
{
|
||||||
|
__highest_j = __s.__current_ - __s.__first_;
|
||||||
|
__matched = true;
|
||||||
|
}
|
||||||
if (__highest_j == _N)
|
if (__highest_j == _N)
|
||||||
__states.clear();
|
__states.clear();
|
||||||
else
|
else
|
||||||
__states.pop_back();
|
__states.pop_back();
|
||||||
break;
|
break;
|
||||||
case __state::__consume_input:
|
case __state::__consume_input:
|
||||||
if (__j == _N)
|
|
||||||
return false;
|
|
||||||
++__current;
|
|
||||||
if (++__j != _N && __states.size() > 1)
|
|
||||||
__states.push_front(_STD::move(__s));
|
|
||||||
__states.pop_back();
|
|
||||||
break;
|
break;
|
||||||
case __state::__accept_and_consume:
|
case __state::__accept_and_consume:
|
||||||
// needs to be changed for the case that this state
|
|
||||||
// consumed more than one character. This will scan
|
|
||||||
// down the deque and insert extra __consume_input
|
|
||||||
// states as necessary
|
|
||||||
__states.push_front(_STD::move(__s));
|
__states.push_front(_STD::move(__s));
|
||||||
__states.pop_back();
|
__states.pop_back();
|
||||||
break;
|
break;
|
||||||
@ -4111,7 +4114,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (!__states.empty());
|
} while (!__states.empty());
|
||||||
if (__highest_j != 0)
|
if (__matched)
|
||||||
{
|
{
|
||||||
__m.__matches_[0].first = __first;
|
__m.__matches_[0].first = __first;
|
||||||
__m.__matches_[0].second = _STD::next(__first, __highest_j);
|
__m.__matches_[0].second = _STD::next(__first, __highest_j);
|
||||||
|
@ -599,4 +599,146 @@ int main()
|
|||||||
std::regex_constants::basic)));
|
std::regex_constants::basic)));
|
||||||
assert(m.size() == 0);
|
assert(m.size() == 0);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "AMB";
|
||||||
|
assert(std::regex_search(s, m, std::regex("A[^[:lower:]]B",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "AmB";
|
||||||
|
assert(!std::regex_search(s, m, std::regex("A[^[:lower:]]B",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "A5B";
|
||||||
|
assert(!std::regex_search(s, m, std::regex("A[^[:lower:]0-9]B",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "A?B";
|
||||||
|
assert(std::regex_search(s, m, std::regex("A[^[:lower:]0-9]B",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "-";
|
||||||
|
assert(std::regex_search(s, m, std::regex("[a[.hyphen.]z]",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "z";
|
||||||
|
assert(std::regex_search(s, m, std::regex("[a[.hyphen.]z]",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "m";
|
||||||
|
assert(!std::regex_search(s, m, std::regex("[a[.hyphen.]z]",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 0);
|
||||||
|
}
|
||||||
|
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "m";
|
||||||
|
assert(std::regex_search(s, m, std::regex("[a[=M=]z]",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "Ch";
|
||||||
|
assert(std::regex_search(s, m, std::regex("[a[.ch.]z]",
|
||||||
|
std::regex_constants::basic | std::regex_constants::icase)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(!m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(!m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == m[0].second);
|
||||||
|
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||||
|
assert(m.position(0) == 0);
|
||||||
|
assert(m.str(0) == s);
|
||||||
|
}
|
||||||
|
std::locale::global(std::locale("C"));
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "m";
|
||||||
|
assert(!std::regex_search(s, m, std::regex("[a[=M=]z]",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::cmatch m;
|
||||||
|
const char s[] = "01a45cef9";
|
||||||
|
assert(std::regex_search(s, m, std::regex("[ace1-9]*",
|
||||||
|
std::regex_constants::basic)));
|
||||||
|
assert(m.size() == 1);
|
||||||
|
assert(m.prefix().matched);
|
||||||
|
assert(m.prefix().first == s);
|
||||||
|
assert(m.prefix().second == m[0].first);
|
||||||
|
assert(m.suffix().matched);
|
||||||
|
assert(m.suffix().first == m[0].second);
|
||||||
|
assert(m.suffix().second == s + std::char_traits<char>::length(s));
|
||||||
|
assert(m.length(0) == 6);
|
||||||
|
assert(m.position(0) == 1);
|
||||||
|
assert(m.str(0) == "1a45ce");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user