Commit e5f35533 by Tim Shen Committed by Tim Shen

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
parent 60c176fb
2015-01-19 Tim Shen <timshen@google.com> 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 PR libstdc++/64584
PR libstdc++/64585 PR libstdc++/64585
* include/bits/regex.h (basic_regex<>::basic_regex, * include/bits/regex.h (basic_regex<>::basic_regex,
......
...@@ -267,53 +267,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -267,53 +267,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"right-curly-bracket", "right-curly-bracket",
"tilde", "tilde",
"DEL", "DEL",
""
}; };
// same as boost string __s(__first, __last);
//static const char* __digraphs[] = for (const auto& __it : __collatenames)
// { if (__s == __it)
// "ae", return string_type(1, __fctyp.widen(
// "Ae", static_cast<char>(&__it - __collatenames)));
// "AE",
// "ch", // TODO Add digraph support:
// "Ch", // http://boost.sourceforge.net/libs/regex/doc/collating_names.html
// "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;
// }
// }
return string_type(); return string_type();
} }
...@@ -324,12 +288,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -324,12 +288,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const
{ {
typedef std::ctype<char_type> __ctype_type; 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 __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}, {"d", ctype_base::digit},
{"w", {ctype_base::alnum, _RegexMask::_S_under}}, {"w", {ctype_base::alnum, _RegexMask::_S_under}},
...@@ -348,21 +310,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -348,21 +310,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{"xdigit", ctype_base::xdigit}, {"xdigit", ctype_base::xdigit},
}; };
std::string __s(__last - __first, '?'); string __s;
__fctyp.narrow(__first, __last, '?', &__s[0]); for (auto __cur = __first; __cur != __last; ++__cur)
__cctyp.tolower(&*__s.begin(), &*__s.begin() + __s.size()); __s += __fctyp.narrow(__fctyp.tolower(*__cur), '?');
for (_ClassnameEntry* __it = __classnames;
__it < *(&__classnames + 1); for (const auto& __it : __classnames)
++__it) if (__s == __it.first)
{
if (__s == __it->first)
{ {
if (__icase if (__icase
&& ((__it->second && ((__it.second
& (ctype_base::lower | ctype_base::upper)) != 0)) & (ctype_base::lower | ctype_base::upper)) != 0))
return ctype_base::alpha; return ctype_base::alpha;
return __it->second; return __it.second;
}
} }
return 0; return 0;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// 28.7(9) Class template regex_traits [re.traits] // 28.7(9) Class template regex_traits [re.traits]
#include <regex> #include <regex>
#include <forward_list>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
void void
...@@ -47,8 +48,29 @@ test01() ...@@ -47,8 +48,29 @@ test01()
VERIFY( c2 == c3 ); 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() int main()
{ {
test01(); test01();
test02();
test03();
return 0; return 0;
} }
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// 28.7 (8) Class template regex_traits [re.traits] // 28.7 (8) Class template regex_traits [re.traits]
#include <regex> #include <regex>
#include <forward_list>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
void void
...@@ -40,8 +41,19 @@ test01() ...@@ -40,8 +41,19 @@ test01()
VERIFY(t.lookup_collatename(name, name+sizeof(name)-1) == "~"); 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() int main()
{ {
test01(); test01();
test02();
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment