// class template regex -*- C++ -*-
-// Copyright (C) 2013-2015 Free Software Foundation, Inc.
+// Copyright (C) 2013-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
* Do not attempt to use it directly. @headername{regex}
*/
-// A non-standard switch to let the user pick the matching algorithm.
-// If _GLIBCXX_REGEX_USE_THOMPSON_NFA is defined, the thompson NFA
-// algorithm will be used. This algorithm is not enabled by default,
-// and cannot be used if the regex contains back-references, but has better
-// (polynomial instead of exponential) worst case performance.
-// See __regex_algo_impl below.
-
namespace std _GLIBCXX_VISIBILITY(default)
{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
namespace __detail
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /// @cond undocumented
// Result of merging regex_match and regex_search.
//
//
// That __match_mode is true means regex_match, else regex_search.
template<typename _BiIter, typename _Alloc,
- typename _CharT, typename _TraitsT,
- _RegexExecutorPolicy __policy,
- bool __match_mode>
+ typename _CharT, typename _TraitsT>
bool
__regex_algo_impl(_BiIter __s,
_BiIter __e,
match_results<_BiIter, _Alloc>& __m,
const basic_regex<_CharT, _TraitsT>& __re,
- regex_constants::match_flag_type __flags)
+ regex_constants::match_flag_type __flags,
+ _RegexExecutorPolicy __policy,
+ bool __match_mode)
{
if (__re._M_automaton == nullptr)
return false;
- typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
+ typename match_results<_BiIter, _Alloc>::_Unchecked& __res = __m;
__m._M_begin = __s;
- __res.resize(__re._M_automaton->_M_sub_count() + 2);
- for (auto& __it : __res)
- __it.matched = false;
+ __m._M_resize(__re._M_automaton->_M_sub_count());
- // __policy is used by testsuites so that they can use Thompson NFA
- // without defining a macro. Users should define
- // _GLIBCXX_REGEX_USE_THOMPSON_NFA if they need to use this approach.
bool __ret;
- if (!__re._M_automaton->_M_has_backref
- && !(__re._M_flags & regex_constants::ECMAScript)
-#ifndef _GLIBCXX_REGEX_USE_THOMPSON_NFA
- && __policy == _RegexExecutorPolicy::_S_alternate
-#endif
- )
+ if ((__re.flags() & regex_constants::__polynomial)
+ || (__policy == _RegexExecutorPolicy::_S_alternate
+ && !__re._M_automaton->_M_has_backref))
{
_Executor<_BiIter, _Alloc, _TraitsT, false>
- __executor(__s, __e, __m, __re, __flags);
+ __executor(__s, __e, __res, __re, __flags);
if (__match_mode)
__ret = __executor._M_match();
else
else
{
_Executor<_BiIter, _Alloc, _TraitsT, true>
- __executor(__s, __e, __m, __re, __flags);
+ __executor(__s, __e, __res, __re, __flags);
if (__match_mode)
__ret = __executor._M_match();
else
for (auto& __it : __res)
if (!__it.matched)
__it.first = __it.second = __e;
- auto& __pre = __res[__res.size()-2];
- auto& __suf = __res[__res.size()-1];
+ auto& __pre = __m._M_prefix();
+ auto& __suf = __m._M_suffix();
if (__match_mode)
{
__pre.matched = false;
__suf.matched = (__suf.first != __suf.second);
}
}
+ else
+ {
+ __m._M_establish_failed_match(__e);
+ }
return __ret;
}
-
-_GLIBCXX_END_NAMESPACE_VERSION
-}
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /// @endcond
+} // namespace __detail
template<typename _Ch_type>
template<typename _Fwd_iter>
"DEL",
};
- string __s(__first, __last);
+ string __s;
+ for (; __first != __last; ++__first)
+ __s += __fctyp.narrow(*__first, 0);
+
for (const auto& __it : __collatenames)
if (__s == __it)
return string_type(1, __fctyp.widen(
};
string __s;
- for (auto __cur = __first; __cur != __last; ++__cur)
- __s += __fctyp.narrow(__fctyp.tolower(*__cur), '?');
+ for (; __first != __last; ++__first)
+ __s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
for (const auto& __it : __classnames)
if (__s == __it.first)
template<typename _Bi_iter, typename _Alloc>
template<typename _Out_iter>
- _Out_iter match_results<_Bi_iter, _Alloc>::
+ _Out_iter
+ match_results<_Bi_iter, _Alloc>::
format(_Out_iter __out,
const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first,
const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last,
match_flag_type __flags) const
{
- _GLIBCXX_DEBUG_ASSERT( ready() );
+ __glibcxx_assert( ready() );
regex_traits<char_type> __traits;
typedef std::ctype<char_type> __ctype_type;
const __ctype_type&
auto __output = [&](size_t __idx)
{
- auto& __sub = _Base_type::operator[](__idx);
+ auto& __sub = (*this)[__idx];
if (__sub.matched)
__out = std::copy(__sub.first, __sub.second, __out);
};
if (__flags & regex_constants::format_sed)
{
- for (; __fmt_first != __fmt_last;)
- if (*__fmt_first == '&')
- {
- __output(0);
- ++__fmt_first;
- }
- else if (*__fmt_first == '\\')
- {
- if (++__fmt_first != __fmt_last
- && __fctyp.is(__ctype_type::digit, *__fmt_first))
- __output(__traits.value(*__fmt_first++, 10));
- else
- *__out++ = '\\';
- }
- else
- *__out++ = *__fmt_first++;
+ bool __escaping = false;
+ for (; __fmt_first != __fmt_last; __fmt_first++)
+ {
+ if (__escaping)
+ {
+ __escaping = false;
+ if (__fctyp.is(__ctype_type::digit, *__fmt_first))
+ __output(__traits.value(*__fmt_first, 10));
+ else
+ *__out++ = *__fmt_first;
+ continue;
+ }
+ if (*__fmt_first == '\\')
+ {
+ __escaping = true;
+ continue;
+ }
+ if (*__fmt_first == '&')
+ {
+ __output(0);
+ continue;
+ }
+ *__out++ = *__fmt_first;
+ }
+ if (__escaping)
+ *__out++ = '\\';
}
else
{
else if (__eat('&'))
__output(0);
else if (__eat('`'))
- __output(_Base_type::size()-2);
+ {
+ auto& __sub = _M_prefix();
+ if (__sub.matched)
+ __out = std::copy(__sub.first, __sub.second, __out);
+ }
else if (__eat('\''))
- __output(_Base_type::size()-1);
+ {
+ auto& __sub = _M_suffix();
+ if (__sub.matched)
+ __out = std::copy(__sub.first, __sub.second, __out);
+ }
else if (__fctyp.is(__ctype_type::digit, *__next))
{
long __num = __traits.value(*__next, 10);
template<typename _Out_iter, typename _Bi_iter,
typename _Rx_traits, typename _Ch_type>
_Out_iter
- regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
- const basic_regex<_Ch_type, _Rx_traits>& __e,
- const _Ch_type* __fmt,
- regex_constants::match_flag_type __flags)
+ __regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
+ const basic_regex<_Ch_type, _Rx_traits>& __e,
+ const _Ch_type* __fmt, size_t __len,
+ regex_constants::match_flag_type __flags)
{
typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
_IterT __i(__first, __last, __e, __flags);
else
{
sub_match<_Bi_iter> __last;
- auto __len = char_traits<_Ch_type>::length(__fmt);
for (; __i != __end; ++__i)
{
if (!(__flags & regex_constants::format_no_copy))
typename _Rx_traits>
bool
regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
- operator==(const regex_iterator& __rhs) const
+ operator==(const regex_iterator& __rhs) const noexcept
{
- return (_M_match.empty() && __rhs._M_match.empty())
- || (_M_begin == __rhs._M_begin
- && _M_end == __rhs._M_end
- && _M_pregex == __rhs._M_pregex
- && _M_flags == __rhs._M_flags
- && _M_match[0] == __rhs._M_match[0]);
+ if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
+ return true;
+ return _M_pregex == __rhs._M_pregex
+ && _M_begin == __rhs._M_begin
+ && _M_end == __rhs._M_end
+ && _M_flags == __rhs._M_flags
+ && _M_match[0] == __rhs._M_match[0];
}
template<typename _Bi_iter,
{
if (__start == _M_end)
{
- _M_match = value_type();
+ _M_pregex = nullptr;
return *this;
}
else
| regex_constants::match_not_null
| regex_constants::match_continuous))
{
- _GLIBCXX_DEBUG_ASSERT(_M_match[0].matched);
- auto& __prefix = _M_match.at(_M_match.size());
+ __glibcxx_assert(_M_match[0].matched);
+ auto& __prefix = _M_match._M_prefix();
__prefix.first = __prefix_first;
__prefix.matched = __prefix.first != __prefix.second;
// [28.12.1.4.5]
_M_flags |= regex_constants::match_prev_avail;
if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
{
- _GLIBCXX_DEBUG_ASSERT(_M_match[0].matched);
- auto& __prefix = _M_match.at(_M_match.size());
+ __glibcxx_assert(_M_match[0].matched);
+ auto& __prefix = _M_match._M_prefix();
__prefix.first = __prefix_first;
__prefix.matched = __prefix.first != __prefix.second;
// [28.12.1.4.5]
_M_match._M_begin = _M_begin;
}
else
- _M_match = value_type();
+ _M_pregex = nullptr;
}
return *this;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
-