From e5f3553320cd121e7952ee7b8ee5cad696336541 Mon Sep 17 00:00:00 2001 From: Tim Shen Date: Mon, 19 Jan 2015 23:00:13 +0000 Subject: [PATCH] re PR libstdc++/64649 (regex_traits::lookup_classname() only works with random access iterators) 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 | 8 ++ libstdc++-v3/include/bits/regex.tcc | 89 +++++-------------- .../28_regex/traits/char/lookup_classname.cc | 22 +++++ .../traits/char/lookup_collatename.cc | 12 +++ 4 files changed, 66 insertions(+), 65 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 371050230a7..fee4452555f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2015-01-19 Tim Shen + + 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 PR libstdc++/64584 diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index 4ea8180fa6f..3f16e66ab2a 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -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(__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(&__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 __ctype_type; - typedef std::ctype __cctype_type; - typedef const pair _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 __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; } diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc index d7216ce11e3..f4c97580ff9 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc @@ -26,6 +26,7 @@ // 28.7(9) Class template regex_traits [re.traits] #include +#include #include void @@ -47,8 +48,29 @@ test01() VERIFY( c2 == c3 ); } +// Test forward iterator +void +test02() +{ + const char strlit[] = "upper"; + std::forward_list s(strlit, strlit + strlen(strlit)); + std::regex_traits traits; + VERIFY(traits.isctype('C', traits.lookup_classname(s.begin(), s.end(), false))); +} + +// icase +void +test03() +{ + std::string s("lower"); + std::regex_traits traits; + VERIFY(traits.isctype('C', traits.lookup_classname(s.begin(), s.end(), true))); +} + int main() { test01(); + test02(); + test03(); return 0; } diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc index 56d0576140e..fac4a240a9b 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc @@ -26,6 +26,7 @@ // 28.7 (8) Class template regex_traits [re.traits] #include +#include #include 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 s(strlit, strlit + strlen(strlit)); + std::regex_traits traits; + VERIFY(traits.lookup_collatename(s.begin(), s.end()) == "~"); +} + int main() { test01(); + test02(); return 0; } -- 2.30.2