mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-19 09:05:17 +08:00
libstdc++: Reduce use of debug containers in <regex>
The std::regex code uses std::map and std::vector, which means that when _GLIBCXX_DEBUG is defined it uses the debug versions of those containers. That no longer compiles, because I changed <regex> to include <bits/stl_map.h> and <bits/stl_vector.h> instead of <map> and <vector>, so the debug versions aren't defined, and std::map doesn't compile. There is also a use of std::stack, which defaults to std::deque which is the debug deque when _GLIBCXX_DEBUG is defined. Using std::map, std::vector, and std::deque is probably a mistake, and we should qualify them with _GLIBCXX_STD_C instead so that the debug versions aren't used. We do not need the overhead of checking our own uses of those containers, which should be correct anyway. The exception is the vector base class of std::match_results, which exposes iterators to users, so can benefit from debug mode checks for its iterators. For other accesses to the vector elements, match_results already does its own checks, so can access the _GLIBCXX_STD_C::vector base class directly. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/bits/regex.h (basic_regex::transform_primary): Use _GLIBCXX_STD_C::vector for local variable. * include/bits/regex.tcc (__regex_algo_impl): Use reference to _GLIBCXX_STD_C::vector base class of match_results. * include/bits/regex_automaton.tcc (_StateSeq:_M_clone): Use _GLIBCXX_STD_C::map and _GLIBCXX_STD_C::deque for local variables. * include/bits/regex_compiler.h (_BracketMatcher): Use _GLIBCXX_STD_C::vector for data members. * include/bits/regex_executor.h (_Executor): Likewise. * include/std/regex [_GLIBCXX_DEBUG]: Include <debug/vector>.
This commit is contained in:
parent
1354603bf7
commit
f5a2d78072
@ -257,7 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
// for details.
|
||||
typedef std::ctype<char_type> __ctype_type;
|
||||
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
|
||||
std::vector<char_type> __s(__first, __last);
|
||||
_GLIBCXX_STD_C::vector<char_type> __s(__first, __last);
|
||||
__fctyp.tolower(__s.data(), __s.data() + __s.size());
|
||||
return this->transform(__s.data(), __s.data() + __s.size());
|
||||
}
|
||||
@ -1697,6 +1697,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
* [n+3] suffix
|
||||
*/
|
||||
typedef std::vector<sub_match<_Bi_iter>, _Alloc> _Base_type;
|
||||
// In debug mode _Base_type is the debug vector, this is the unsafe one:
|
||||
typedef _GLIBCXX_STD_C::vector<sub_match<_Bi_iter>, _Alloc> _Unchecked;
|
||||
typedef std::iterator_traits<_Bi_iter> __iter_traits;
|
||||
typedef regex_constants::match_flag_type match_flag_type;
|
||||
|
||||
@ -1773,7 +1775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
* @retval true The object has a fully-established result state.
|
||||
* @retval false The object is not ready.
|
||||
*/
|
||||
bool ready() const noexcept { return !_Base_type::empty(); }
|
||||
bool ready() const noexcept { return !_Unchecked::empty(); }
|
||||
|
||||
/**
|
||||
* @name 28.10.2 Size
|
||||
@ -1791,11 +1793,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
*/
|
||||
size_type
|
||||
size() const noexcept
|
||||
{ return _Base_type::empty() ? 0 : _Base_type::size() - 3; }
|
||||
{ return _Unchecked::empty() ? 0 : _Unchecked::size() - 3; }
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{ return _Base_type::max_size() - 3; }
|
||||
{ return _Unchecked::max_size() - 3; }
|
||||
|
||||
/**
|
||||
* @brief Indicates if the %match_results contains no results.
|
||||
@ -1869,7 +1871,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
{
|
||||
__glibcxx_assert( ready() );
|
||||
return __sub < size()
|
||||
? _Base_type::operator[](__sub)
|
||||
? _Unchecked::operator[](__sub)
|
||||
: _M_unmatched_sub();
|
||||
}
|
||||
|
||||
@ -2045,7 +2047,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
// (plus additional objects for prefix, suffix and unmatched sub).
|
||||
void
|
||||
_M_resize(unsigned int __size)
|
||||
{ _Base_type::assign(__size + 3, sub_match<_Bi_iter>{}); }
|
||||
{ _Unchecked::assign(__size + 3, sub_match<_Bi_iter>{}); }
|
||||
|
||||
// Set state to a failed match for the given past-the-end iterator.
|
||||
void
|
||||
@ -2053,32 +2055,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
{
|
||||
sub_match<_Bi_iter> __sm;
|
||||
__sm.first = __sm.second = __end;
|
||||
_Base_type::assign(3, __sm);
|
||||
_Unchecked::assign(3, __sm);
|
||||
}
|
||||
|
||||
const_reference
|
||||
_M_unmatched_sub() const
|
||||
{ return _Base_type::operator[](_Base_type::size() - 3); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 3); }
|
||||
|
||||
sub_match<_Bi_iter>&
|
||||
_M_unmatched_sub()
|
||||
{ return _Base_type::operator[](_Base_type::size() - 3); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 3); }
|
||||
|
||||
const_reference
|
||||
_M_prefix() const
|
||||
{ return _Base_type::operator[](_Base_type::size() - 2); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 2); }
|
||||
|
||||
sub_match<_Bi_iter>&
|
||||
_M_prefix()
|
||||
{ return _Base_type::operator[](_Base_type::size() - 2); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 2); }
|
||||
|
||||
const_reference
|
||||
_M_suffix() const
|
||||
{ return _Base_type::operator[](_Base_type::size() - 1); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 1); }
|
||||
|
||||
sub_match<_Bi_iter>&
|
||||
_M_suffix()
|
||||
{ return _Base_type::operator[](_Base_type::size() - 1); }
|
||||
{ return _Unchecked::operator[](_Unchecked::size() - 1); }
|
||||
|
||||
_Bi_iter _M_begin;
|
||||
/// @endcond
|
||||
|
@ -56,7 +56,7 @@ namespace __detail
|
||||
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;
|
||||
__m._M_resize(__re._M_automaton->_M_sub_count());
|
||||
|
||||
@ -66,7 +66,7 @@ namespace __detail
|
||||
&& !__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
|
||||
@ -75,7 +75,7 @@ namespace __detail
|
||||
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
|
||||
|
@ -194,8 +194,8 @@ namespace __detail
|
||||
_StateSeq<_TraitsT>
|
||||
_StateSeq<_TraitsT>::_M_clone()
|
||||
{
|
||||
std::map<_StateIdT, _StateIdT> __m;
|
||||
std::stack<_StateIdT> __stack;
|
||||
_GLIBCXX_STD_C::map<_StateIdT, _StateIdT> __m;
|
||||
std::stack<_StateIdT, _GLIBCXX_STD_C::deque<_StateIdT>> __stack;
|
||||
__stack.push(_M_start);
|
||||
while (!__stack.empty())
|
||||
{
|
||||
|
@ -538,10 +538,10 @@ namespace __detail
|
||||
{ }
|
||||
|
||||
private:
|
||||
std::vector<_CharT> _M_char_set;
|
||||
std::vector<_StringT> _M_equiv_set;
|
||||
std::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
|
||||
std::vector<_CharClassT> _M_neg_class_set;
|
||||
_GLIBCXX_STD_C::vector<_CharT> _M_char_set;
|
||||
_GLIBCXX_STD_C::vector<_StringT> _M_equiv_set;
|
||||
_GLIBCXX_STD_C::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
|
||||
_GLIBCXX_STD_C::vector<_CharClassT> _M_neg_class_set;
|
||||
_CharClassT _M_class_set;
|
||||
_TransT _M_translator;
|
||||
const _TraitsT& _M_traits;
|
||||
|
@ -60,7 +60,7 @@ namespace __detail
|
||||
public:
|
||||
typedef typename iterator_traits<_BiIter>::value_type _CharT;
|
||||
typedef basic_regex<_CharT, _TraitsT> _RegexT;
|
||||
typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec;
|
||||
typedef _GLIBCXX_STD_C::vector<sub_match<_BiIter>, _Alloc> _ResultsVec;
|
||||
typedef regex_constants::match_flag_type _FlagT;
|
||||
typedef typename _TraitsT::char_class_type _ClassT;
|
||||
typedef _NFA<_TraitsT> _NFAT;
|
||||
@ -215,7 +215,7 @@ namespace __detail
|
||||
_BiIter* _M_get_sol_pos() { return nullptr; }
|
||||
|
||||
// Saves states that need to be considered for the next character.
|
||||
vector<pair<_StateIdT, _ResultsVec>> _M_match_queue;
|
||||
_GLIBCXX_STD_C::vector<pair<_StateIdT, _ResultsVec>> _M_match_queue;
|
||||
// Indicates which states are already visited.
|
||||
bool* _M_visited_states;
|
||||
// To record current solution.
|
||||
@ -248,7 +248,7 @@ namespace __detail
|
||||
const _RegexT& _M_re;
|
||||
const _NFAT& _M_nfa;
|
||||
_ResultsVec& _M_results;
|
||||
vector<pair<_BiIter, int>> _M_rep_count;
|
||||
_GLIBCXX_STD_C::vector<pair<_BiIter, int>> _M_rep_count;
|
||||
_State_info<__search_mode, _ResultsVec> _M_states;
|
||||
_FlagT _M_flags;
|
||||
// Do we have a solution so far?
|
||||
|
@ -55,6 +55,9 @@
|
||||
#include <bits/stl_vector.h>
|
||||
#include <bits/stl_bvector.h>
|
||||
#include <bits/vector.tcc>
|
||||
#ifdef _GLIBCXX_DEBUG
|
||||
# include <debug/vector>
|
||||
#endif
|
||||
#include <bits/regex_constants.h>
|
||||
#include <bits/regex_error.h>
|
||||
#include <bits/regex_automaton.h>
|
||||
|
Loading…
Reference in New Issue
Block a user