Make std::match_results::_M_resize more useful
authorJonathan Wakely <jwakely@redhat.com>
Tue, 14 May 2019 12:19:05 +0000 (13:19 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 14 May 2019 12:19:05 +0000 (13:19 +0100)
As both callers of match_results::_M_resize(unsigned) immediately follow
it with a loop to update the value of each sub_match, that behaviour can
be moved into _M_resize itself. The first caller fills the container
with unmatched subs, which can be done with vector::assign, and the
second caller clears the container to establish a specific state, which
can be provided by a new member function specific to that purpose.

Tangentially, I also noticed that match_results::max_size() doesn't
account for the three special sub_match objects that are always present
in a fully established result state. This patch also fixes that.

* include/bits/regex.h (match_results::max_size()): Adjust return
value to account for prefix/suffix/unmatched subs.
(match_results::_M_resize(unsigned int)): Use _Base_type::assign to
reset the contained sub matches.
(match_results::_M_establish_failed_match(_Bi_iter)): Add new member
function to set result state following a failed match.
* include/bits/regex.tcc (__regex_algo_impl): Remove loop to set
sub_match states after _M_resize. Use _M_establish_failed_match.

From-SVN: r271167

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/regex.tcc

index 995f2ce1d45ef69a906b455665f487e8fce1e100..3cfcd0623c173c26d69de170f268b401687d04e9 100644 (file)
@@ -1,5 +1,14 @@
 2019-05-14  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/bits/regex.h (match_results::max_size()): Adjust return
+       value to account for prefix/suffix/unmatched subs.
+       (match_results::_M_resize(unsigned int)): Use _Base_type::assign to
+       reset the contained sub matches.
+       (match_results::_M_establish_failed_match(_Bi_iter)): Add new member
+       function to set result state following a failed match.
+       * include/bits/regex.tcc (__regex_algo_impl): Remove loop to set
+       sub_match states after _M_resize. Use _M_establish_failed_match.
+
        PR libstdc++/69724
        * include/std/thread (thread::_State_impl, thread::_S_make_state):
        Replace single _Callable parameter with variadic _Args pack, to
index 76219b5ae3ba9d794f0bd8114ff887d8ea8915f9..b30b41a075953a89341341e319e2533aabbefc53 100644 (file)
@@ -1707,7 +1707,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
       size_type
       max_size() const noexcept
-      { return _Base_type::max_size(); }
+      { return _Base_type::max_size() - 3; }
 
       /**
        * @brief Indicates if the %match_results contains no results.
@@ -1953,9 +1953,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
                                    const basic_regex<_Cp, _Rp>&,
                                    regex_constants::match_flag_type);
 
+      // Reset contents to __size unmatched sub_match objects
+      // (plus additional objects for prefix, suffix and unmatched sub).
       void
       _M_resize(unsigned int __size)
-      { _Base_type::resize(__size + 3); }
+      { _Base_type::assign(__size + 3, sub_match<_Bi_iter>{}); }
+
+      // Set state to a failed match for the given past-the-end iterator.
+      void
+      _M_establish_failed_match(_Bi_iter __end)
+      {
+       sub_match<_Bi_iter> __sm;
+       __sm.first = __sm.second = __end;
+       _Base_type::assign(3, __sm);
+      }
 
       const_reference
       _M_unmatched_sub() const
index dbe348dbfe88ba691555ef102ca112e57edbf6c9..53cf1ffa01e039b49e05a80699ec88bdd106e3a5 100644 (file)
@@ -59,8 +59,6 @@ namespace __detail
       typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
       __m._M_begin = __s;
       __m._M_resize(__re._M_automaton->_M_sub_count());
-      for (auto& __it : __res)
-       __it.matched = false;
 
       bool __ret;
       if ((__re.flags() & regex_constants::__polynomial)
@@ -111,12 +109,7 @@ namespace __detail
        }
       else
        {
-         __m._M_resize(0);
-         for (auto& __it : __res)
-           {
-             __it.matched = false;
-             __it.first = __it.second = __e;
-           }
+         __m._M_establish_failed_match(__e);
        }
       return __ret;
     }