re PR libstdc++/64649 (regex_traits::lookup_classname() only works with random access...
authorTim Shen <timshen@google.com>
Mon, 19 Jan 2015 23:00:13 +0000 (23:00 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Mon, 19 Jan 2015 23:00:13 +0000 (23:00 +0000)
PR libstdc++/64649
* include/bits/regex.tcc (regex_traits<>::lookup_collatename,
regex_traits<>::lookup_classname): Support forward iterators.
* testsuite/28_regex/traits/char/lookup_classname.cc: New testcases.
* testsuite/28_regex/traits/char/lookup_collatename.cc: New testcase.

From-SVN: r219866

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc
libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc

index 371050230a77842aef50dc0689a5212d0db39ef0..fee4452555f4b77a2716130e44263f0dbb21c16d 100644 (file)
@@ -1,3 +1,11 @@
+2015-01-19  Tim Shen  <timshen@google.com>
+
+       PR libstdc++/64649
+       * include/bits/regex.tcc (regex_traits<>::lookup_collatename,
+       regex_traits<>::lookup_classname): Support forward iterators.
+       * testsuite/28_regex/traits/char/lookup_classname.cc: New testcases.
+       * testsuite/28_regex/traits/char/lookup_collatename.cc: New testcase.
+
 2015-01-19  Tim Shen  <timshen@google.com>
 
        PR libstdc++/64584
index 4ea8180fa6f63d667ac01b48d9cac0f1ce22ca7a..3f16e66ab2a468132de1e063425071bc4247f18c 100644 (file)
@@ -267,53 +267,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          "right-curly-bracket",
          "tilde",
          "DEL",
-         ""
        };
 
-      // same as boost
-      //static const char* __digraphs[] =
-      //  {
-      //    "ae",
-      //    "Ae",
-      //    "AE",
-      //    "ch",
-      //    "Ch",
-      //    "CH",
-      //    "ll",
-      //    "Ll",
-      //    "LL",
-      //    "ss",
-      //    "Ss",
-      //    "SS",
-      //    "nj",
-      //    "Nj",
-      //    "NJ",
-      //    "dz",
-      //    "Dz",
-      //    "DZ",
-      //    "lj",
-      //    "Lj",
-      //    "LJ",
-      //    ""
-      //  };
-
-      std::string __s(__last - __first, '?');
-      __fctyp.narrow(__first, __last, '?', &*__s.begin());
-
-      for (unsigned int __i = 0; *__collatenames[__i]; __i++)
-       if (__s == __collatenames[__i])
-         return string_type(1, __fctyp.widen(static_cast<char>(__i)));
-
-      //for (unsigned int __i = 0; *__digraphs[__i]; __i++)
-      //  {
-      //    const char* __now = __digraphs[__i];
-      //    if (__s == __now)
-      //      {
-      //       string_type ret(__s.size(), __fctyp.widen('?'));
-      //       __fctyp.widen(__now, __now + 2/* ouch */, &*ret.begin());
-      //       return ret;
-      //      }
-      //  }
+      string __s(__first, __last);
+      for (const auto& __it : __collatenames)
+       if (__s == __it)
+         return string_type(1, __fctyp.widen(
+           static_cast<char>(&__it - __collatenames)));
+
+      // TODO Add digraph support:
+      // http://boost.sourceforge.net/libs/regex/doc/collating_names.html
+
       return string_type();
     }
 
@@ -324,12 +288,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const
     {
       typedef std::ctype<char_type> __ctype_type;
-      typedef std::ctype<char> __cctype_type;
-      typedef const pair<const char*, char_class_type> _ClassnameEntry;
       const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-      const __cctype_type& __cctyp(use_facet<__cctype_type>(_M_locale));
 
-      static _ClassnameEntry __classnames[] =
+      // Mappings from class name to class mask.
+      static const pair<const char*, char_class_type> __classnames[] =
       {
        {"d", ctype_base::digit},
        {"w", {ctype_base::alnum, _RegexMask::_S_under}},
@@ -348,22 +310,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        {"xdigit", ctype_base::xdigit},
       };
 
-      std::string __s(__last - __first, '?');
-      __fctyp.narrow(__first, __last, '?', &__s[0]);
-      __cctyp.tolower(&*__s.begin(), &*__s.begin() + __s.size());
-      for (_ClassnameEntry* __it = __classnames;
-          __it < *(&__classnames + 1);
-          ++__it)
-       {
-         if (__s == __it->first)
-           {
-             if (__icase
-                 && ((__it->second
-                      & (ctype_base::lower | ctype_base::upper)) != 0))
-               return ctype_base::alpha;
-             return __it->second;
-           }
-       }
+      string __s;
+      for (auto __cur = __first; __cur != __last; ++__cur)
+       __s += __fctyp.narrow(__fctyp.tolower(*__cur), '?');
+
+      for (const auto& __it : __classnames)
+       if (__s == __it.first)
+         {
+           if (__icase
+               && ((__it.second
+                    & (ctype_base::lower | ctype_base::upper)) != 0))
+             return ctype_base::alpha;
+           return __it.second;
+         }
       return 0;
     }
 
index d7216ce11e3fc29bca48b642cb904fb3ae6bd064..f4c97580ff9ba8c2e8ad68c1233e2e31c544718a 100644 (file)
@@ -26,6 +26,7 @@
 // 28.7(9) Class template regex_traits [re.traits]
 
 #include <regex>
+#include <forward_list>
 #include <testsuite_hooks.h>
 
 void
@@ -47,8 +48,29 @@ test01()
        VERIFY( c2 == c3 );
 }
 
+// Test forward iterator
+void
+test02()
+{
+  const char strlit[] = "upper";
+  std::forward_list<char> s(strlit, strlit + strlen(strlit));
+  std::regex_traits<char> traits;
+  VERIFY(traits.isctype('C', traits.lookup_classname(s.begin(), s.end(), false)));
+}
+
+// icase
+void
+test03()
+{
+  std::string s("lower");
+  std::regex_traits<char> traits;
+  VERIFY(traits.isctype('C', traits.lookup_classname(s.begin(), s.end(), true)));
+}
+
 int main()
 {
        test01();
+       test02();
+       test03();
        return 0;
 }
index 56d0576140e48bef1df36e374c8caea92cb6ca6f..fac4a240a9bd65fd37f381b791f2df485b4d3f18 100644 (file)
@@ -26,6 +26,7 @@
 // 28.7 (8) Class template regex_traits [re.traits]
 
 #include <regex>
+#include <forward_list>
 #include <testsuite_hooks.h>
 
 void
@@ -40,8 +41,19 @@ test01()
   VERIFY(t.lookup_collatename(name, name+sizeof(name)-1) == "~");
 }
 
+// Test forward iterator.
+void
+test02()
+{
+  const char strlit[] = "tilde";
+  std::forward_list<char> s(strlit, strlit + strlen(strlit));
+  std::regex_traits<char> traits;
+  VERIFY(traits.lookup_collatename(s.begin(), s.end()) == "~");
+}
+
 int main()
 {
        test01();
+       test02();
        return 0;
 }