re PR libstdc++/64239 (regex_iterator::operator= should copy match_results::position)
authorTim Shen <timshen@google.com>
Sat, 13 Dec 2014 22:19:18 +0000 (22:19 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Sat, 13 Dec 2014 22:19:18 +0000 (22:19 +0000)
PR libstdc++/64239
* include/bits/regex.h (match_results<>::match_results,
match_results<>::operator=, match_results<>::position,
match_results<>::swap): Remove match_results::_M_in_iterator.
Fix ctor/assign/swap.
* include/bits/regex.tcc: (__regex_algo_impl<>,
regex_iterator<>::operator++): Set match_results::_M_begin as
"start position".
* testsuite/28_regex/iterators/regex_iterator/char/
string_position_01.cc: Test cases.

From-SVN: r218710

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc

index 0df6b3b910740962913fb3438a1e5cf4d31f2783..4e79925ff0fa888a94f1ea764cc3f753093ef0c5 100644 (file)
@@ -1,3 +1,16 @@
+2014-12-13  Tim Shen  <timshen@google.com>
+
+       PR libstdc++/64239
+       * include/bits/regex.h (match_results<>::match_results,
+       match_results<>::operator=, match_results<>::position,
+       match_results<>::swap): Remove match_results::_M_in_iterator.
+       Fix ctor/assign/swap.
+       * include/bits/regex.tcc: (__regex_algo_impl<>,
+       regex_iterator<>::operator++): Set match_results::_M_begin as
+       "start position".
+       * testsuite/28_regex/iterators/regex_iterator/char/
+       string_position_01.cc: Test cases.
+
 2014-12-13  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/experimental/any (any): Remove allocator support and update
index cb6bc93251a86a8734ffd0c4ac4422d529129bed..3afec37ab165234abf8bca28ac40661fd62ad9f8 100644 (file)
@@ -1563,42 +1563,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       explicit
       match_results(const _Alloc& __a = _Alloc())
-      : _Base_type(__a), _M_in_iterator(false)
+      : _Base_type(__a)
       { }
 
       /**
        * @brief Copy constructs a %match_results.
        */
-      match_results(const match_results& __rhs)
-      : _Base_type(__rhs), _M_in_iterator(false)
-      { }
+      match_results(const match_results& __rhs) = default;
 
       /**
        * @brief Move constructs a %match_results.
        */
-      match_results(match_results&& __rhs) noexcept
-      : _Base_type(std::move(__rhs)), _M_in_iterator(false)
-      { }
+      match_results(match_results&& __rhs) noexcept = default;
 
       /**
        * @brief Assigns rhs to *this.
        */
       match_results&
-      operator=(const match_results& __rhs)
-      {
-       match_results(__rhs).swap(*this);
-       return *this;
-      }
+      operator=(const match_results& __rhs) = default;
 
       /**
        * @brief Move-assigns rhs to *this.
        */
       match_results&
-      operator=(match_results&& __rhs)
-      {
-       match_results(std::move(__rhs)).swap(*this);
-       return *this;
-      }
+      operator=(match_results&& __rhs) = default;
 
       /**
        * @brief Destroys a %match_results object.
@@ -1685,13 +1673,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       difference_type
       position(size_type __sub = 0) const
       {
-       // [28.12.1.4.5]
-       if (_M_in_iterator)
-         return __sub < size() ? std::distance(_M_begin,
-                                               (*this)[__sub].first) : -1;
-       else
-         return __sub < size() ? std::distance(this->prefix().first,
-                                               (*this)[__sub].first) : -1;
+       return __sub < size() ? std::distance(_M_begin,
+                                             (*this)[__sub].first) : -1;
       }
 
       /**
@@ -1876,7 +1859,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       void
       swap(match_results& __that)
-      { _Base_type::swap(__that); }
+      {
+       _Base_type::swap(__that);
+       swap(_M_begin, __that._M_begin);
+      }
       //@}
 
     private:
@@ -1894,7 +1880,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                    regex_constants::match_flag_type);
 
       _Bi_iter _M_begin;
-      bool     _M_in_iterator;
     };
 
   typedef match_results<const char*>             cmatch;
index 96924024c906a55da37ab4d4611a0b75c508b023..b6764288d19fd34e4f16a517a188c81fecd81416 100644 (file)
@@ -62,6 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return false;
 
       typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
+      __m._M_begin = __s;
       __res.resize(__re._M_automaton->_M_sub_count() + 2);
       for (auto& __it : __res)
        __it.matched = false;
@@ -572,7 +573,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                      auto& __prefix = _M_match.at(_M_match.size());
                      __prefix.first = __prefix_first;
                      __prefix.matched = __prefix.first != __prefix.second;
-                     _M_match._M_in_iterator = true;
+                     // [28.12.1.4.5]
                      _M_match._M_begin = _M_begin;
                      return *this;
                    }
@@ -587,7 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              auto& __prefix = _M_match.at(_M_match.size());
              __prefix.first = __prefix_first;
              __prefix.matched = __prefix.first != __prefix.second;
-             _M_match._M_in_iterator = true;
+             // [28.12.1.4.5]
              _M_match._M_begin = _M_begin;
            }
          else
index 5fa4ea774923fdd85e45c622843cf4bd1bb251c1..91aa06137f5b0a8dc71a7da4110a7036bc579298 100644 (file)
@@ -24,6 +24,7 @@
 // Tests iter->position() behavior
 
 #include <regex>
+#include <tuple>
 #include <testsuite_hooks.h>
 
 void
@@ -41,9 +42,53 @@ test01()
   }
 }
 
+// PR libstdc++/64239
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::regex re("\\w+");
+  std::string s("-a-b-c-");
+
+  std::tuple<int, int, const char*> expected[] =
+  {
+    std::make_tuple(1, 1, "a"),
+    std::make_tuple(3, 1, "b"),
+    std::make_tuple(5, 1, "c"),
+  };
+
+  int i = 0;
+  for (auto it1 = std::sregex_iterator(s.begin(), s.end(), re),
+       end = std::sregex_iterator(); it1 != end; ++it1, i++)
+    {
+      auto it2 = it1;
+      VERIFY(it1->position() == std::get<0>(expected[i]));
+      VERIFY(it1->length() == std::get<1>(expected[i]));
+      VERIFY(it1->str() == std::get<2>(expected[i]));
+      VERIFY(it2->position() == std::get<0>(expected[i]));
+      VERIFY(it2->length() == std::get<1>(expected[i]));
+      VERIFY(it2->str() == std::get<2>(expected[i]));
+    }
+}
+
+void
+test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::smatch m;
+  std::string s = "abcde";
+  std::regex_search(s, m, std::regex("bcd"));
+  VERIFY(m.position() == 1);
+  VERIFY(m.position() == m.prefix().length());
+}
+
 int
 main()
 {
   test01();
+  test02();
+  test03();
   return 0;
 }