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
This commit is contained in:
Tim Shen 2015-01-19 23:00:13 +00:00 committed by Tim Shen
parent 60c176fb45
commit e5f3553320
4 changed files with 64 additions and 63 deletions

View 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

View 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",
// ""
// };
string __s(__first, __last);
for (const auto& __it : __collatenames)
if (__s == __it)
return string_type(1, __fctyp.widen(
static_cast<char>(&__it - __collatenames)));
std::string __s(__last - __first, '?');
__fctyp.narrow(__first, __last, '?', &*__s.begin());
// TODO Add digraph support:
// http://boost.sourceforge.net/libs/regex/doc/collating_names.html
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();
}
@ -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;
}

View 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;
}

View 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;
}