aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-12-15 16:56:42 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-12-15 16:56:42 +0000
commitca13fb7f5daa9b61ed9c94c74c326ca437ef6b78 (patch)
treea5a075673330f5abd003895df2113fd69e3dac4b
parent3a5c1f603eabdf9e21e91882180dec0de7b5a757 (diff)
downloadgcc-ca13fb7f5daa9b61ed9c94c74c326ca437ef6b78.zip
gcc-ca13fb7f5daa9b61ed9c94c74c326ca437ef6b78.tar.gz
gcc-ca13fb7f5daa9b61ed9c94c74c326ca437ef6b78.tar.bz2
locale_facets.tcc (num_get::do_get(bool&)): Fail as soon as the begins of both truename and falsename stop to match...
2003-12-15 Paolo Carlini <pcarlini@suse.de> * include/bits/locale_facets.tcc (num_get::do_get(bool&)): Fail as soon as the begins of both truename and falsename stop to match; always leave __beg one position beyond the last char successfully matched. * testsuite/22_locale/num_get/get/char/8.cc: New. * testsuite/22_locale/num_get/get/wchar_t/8.cc: Likewise. 2003-12-15 Paolo Carlini <pcarlini@suse.de> * include/bits/locale_facets.h (_M_widen): Reserve space for all the possible widened chars. * config/locale/generic/ctype_members.cc (_M_initialize_ctype): Compute at construction time all the possible widened chars. (do_widen): Tweak, simplify. * config/locale/gnu/ctype_members.cc: Likewise. * testsuite/performance/narrow_widen_wchar_t.cc: Add tests for the array versions. From-SVN: r74636
-rw-r--r--libstdc++-v3/ChangeLog20
-rw-r--r--libstdc++-v3/config/locale/generic/ctype_members.cc16
-rw-r--r--libstdc++-v3/config/locale/gnu/ctype_members.cc31
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h6
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc52
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/8.cc70
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/8.cc70
-rw-r--r--libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc22
8 files changed, 216 insertions, 71 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 27e23bf..e0f17c3 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,23 @@
+2003-12-15 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/locale_facets.tcc (num_get::do_get(bool&)):
+ Fail as soon as the begins of both truename and falsename
+ stop to match; always leave __beg one position beyond the
+ last char successfully matched.
+ * testsuite/22_locale/num_get/get/char/8.cc: New.
+ * testsuite/22_locale/num_get/get/wchar_t/8.cc: Likewise.
+
+2003-12-15 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/locale_facets.h (_M_widen): Reserve space
+ for all the possible widened chars.
+ * config/locale/generic/ctype_members.cc (_M_initialize_ctype):
+ Compute at construction time all the possible widened chars.
+ (do_widen): Tweak, simplify.
+ * config/locale/gnu/ctype_members.cc: Likewise.
+ * testsuite/performance/narrow_widen_wchar_t.cc: Add tests
+ for the array versions.
+
2003-12-12 Paolo Carlini <pcarlini@suse.de>
Benjamin Kosnik <bkoz@redhat.com>
diff --git a/libstdc++-v3/config/locale/generic/ctype_members.cc b/libstdc++-v3/config/locale/generic/ctype_members.cc
index 517df4c..e94d447 100644
--- a/libstdc++-v3/config/locale/generic/ctype_members.cc
+++ b/libstdc++-v3/config/locale/generic/ctype_members.cc
@@ -185,12 +185,7 @@ namespace std
wchar_t
ctype<wchar_t>::
do_widen(char __c) const
- {
- const unsigned char __uc = static_cast<unsigned char>(__c);
- if (__uc < 128)
- return _M_widen[__uc];
- return btowc(__uc);
- }
+ { return _M_widen[static_cast<unsigned char>(__c)]; }
const char*
ctype<wchar_t>::
@@ -198,11 +193,7 @@ namespace std
{
while (__lo < __hi)
{
- const unsigned char __uc = static_cast<unsigned char>(*__lo);
- if (__uc < 128)
- *__dest = _M_widen[__uc];
- else
- *__dest = btowc(__uc);
+ *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
++__lo;
++__dest;
}
@@ -264,7 +255,8 @@ namespace std
_M_narrow_ok = true;
else
_M_narrow_ok = false;
- for (int __i = 0; __i < 128; ++__i)
+ for (size_t __i = 0;
+ __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__i);
}
#endif // _GLIBCXX_USE_WCHAR_T
diff --git a/libstdc++-v3/config/locale/gnu/ctype_members.cc b/libstdc++-v3/config/locale/gnu/ctype_members.cc
index 673b511..998737b 100644
--- a/libstdc++-v3/config/locale/gnu/ctype_members.cc
+++ b/libstdc++-v3/config/locale/gnu/ctype_members.cc
@@ -191,47 +191,25 @@ namespace std
wchar_t
ctype<wchar_t>::
do_widen(char __c) const
- {
- const unsigned char __uc = static_cast<unsigned char>(__c);
- if (__uc < 128)
- return _M_widen[__uc];
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __c_locale __old = __uselocale(_M_c_locale_ctype);
-#endif
- const wchar_t __wc = btowc(__uc);
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __uselocale(__old);
-#endif
- return __wc;
- }
+ { return _M_widen[static_cast<unsigned char>(__c)]; }
const char*
ctype<wchar_t>::
do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
{
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __c_locale __old = __uselocale(_M_c_locale_ctype);
-#endif
while (__lo < __hi)
{
- const unsigned char __uc = static_cast<unsigned char>(*__lo);
- if (__uc < 128)
- *__dest = _M_widen[__uc];
- else
- *__dest = btowc(__uc);
+ *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
++__lo;
++__dest;
}
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __uselocale(__old);
-#endif
return __hi;
}
char
ctype<wchar_t>::
do_narrow(wchar_t __wc, char __dfault) const
- {
+ {
if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
return _M_narrow[__wc];
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
@@ -298,7 +276,8 @@ namespace std
_M_narrow_ok = true;
else
_M_narrow_ok = false;
- for (int __i = 0; __i < 128; ++__i)
+ for (size_t __i = 0;
+ __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__i);
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__uselocale(__old);
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 7a24b9b..83d77c8 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -446,10 +446,10 @@ namespace std
protected:
__c_locale _M_c_locale_ctype;
- // Pre-computed narrowed and widened chars in the range 0-127.
- bool _M_narrow_ok;
+ // Pre-computed narrowed and widened chars.
+ bool _M_narrow_ok;
char _M_narrow[128];
- wint_t _M_widen[128];
+ wint_t _M_widen[1 + static_cast<unsigned char>(-1)];
public:
// Data Members:
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index a583e0e..84f0b88 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -473,38 +473,36 @@ namespace std
__use_cache<__cache_type> __uc;
const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc);
- const size_t __tn = __traits_type::length(__lc->_M_truename) - 1;
- const size_t __fn = __traits_type::length(__lc->_M_falsename) - 1;
+ const size_t __tn = __traits_type::length(__lc->_M_truename);
+ const size_t __fn = __traits_type::length(__lc->_M_falsename);
- bool __testf = false;
- bool __testt = false;
- for (size_t __n = 0; __beg != __end; ++__n)
+ bool __testf = true;
+ bool __testt = true;
+ size_t __n;
+ for (__n = 0; __beg != __end; ++__n, ++__beg)
{
- const char_type __c = *__beg;
- ++__beg;
-
- if (__n <= __fn)
- __testf = __traits_type::eq(__c, __lc->_M_falsename[__n]);
+ if (__testf)
+ if (__n < __fn)
+ __testf = __traits_type::eq(*__beg, __lc->_M_falsename[__n]);
+ else
+ break;
- if (__n <= __tn)
- __testt = __traits_type::eq(__c, __lc->_M_truename[__n]);
+ if (__testt)
+ if (__n < __tn)
+ __testt = __traits_type::eq(*__beg, __lc->_M_truename[__n]);
+ else
+ break;
- if (!(__testf || __testt))
- {
- __err |= ios_base::failbit;
- break;
- }
- else if (__testf && __n == __fn)
- {
- __v = 0;
- break;
- }
- else if (__testt && __n == __tn)
- {
- __v = 1;
- break;
- }
+ if (!__testf && !__testt)
+ break;
}
+ if (__testf && __n == __fn)
+ __v = 0;
+ else if (__testt && __n == __tn)
+ __v = 1;
+ else
+ __err |= ios_base::failbit;
+
if (__beg == __end)
__err |= ios_base::eofbit;
}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/8.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/8.cc
new file mode 100644
index 0000000..d3f24f9
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/8.cc
@@ -0,0 +1,70 @@
+// 2003-12-15 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2003 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1.1 num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ bool b;
+
+ // cache the num_get facet
+ istringstream iss;
+ const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
+ const ios_base::iostate goodbit = ios_base::goodbit;
+ const ios_base::iostate failbit = ios_base::failbit;
+ ios_base::iostate err;
+ iterator_type end;
+
+ iss.setf(ios_base::boolalpha);
+ iss.str("faLse");
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == 'L' );
+ VERIFY( err == failbit );
+
+ iss.str("falsr");
+ iss.clear();
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == 'r' );
+ VERIFY( err == failbit );
+
+ iss.str("trus");
+ iss.clear();
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == 's' );
+ VERIFY( err == failbit );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/8.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/8.cc
new file mode 100644
index 0000000..fbba3a5
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/8.cc
@@ -0,0 +1,70 @@
+// 2003-12-15 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2003 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1.1 num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ bool b;
+
+ // cache the num_get facet
+ wistringstream iss;
+ const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
+ const ios_base::iostate goodbit = ios_base::goodbit;
+ const ios_base::iostate failbit = ios_base::failbit;
+ ios_base::iostate err;
+ iterator_type end;
+
+ iss.setf(ios_base::boolalpha);
+ iss.str(L"faLse");
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == L'L' );
+ VERIFY( err == failbit );
+
+ iss.str(L"falsr");
+ iss.clear();
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == L'r' );
+ VERIFY( err == failbit );
+
+ iss.str(L"trus");
+ iss.clear();
+ err = goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, b);
+ VERIFY( *end == L's' );
+ VERIFY( err == failbit );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc b/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
index 1081bf5..053f807 100644
--- a/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
+++ b/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
@@ -35,25 +35,41 @@ int main()
time_counter time;
resource_counter resource;
- const long iters = 200000000;
+ wchar_t bufwc[] = L"M'innamoravo di tutto (Fabrizio De Andre')";
+ char bufc[sizeof(bufwc) / sizeof(wchar_t)];
locale loc;
const ctype<wchar_t>& ct = use_facet<ctype<wchar_t> >(loc);
// narrow
start_counters(time, resource);
- for (long i = 0; i < iters; ++i)
+ for (long i = 0; i < 200000000; ++i)
ct.narrow(i % 128, '*');
stop_counters(time, resource);
report_performance(__FILE__, "narrow", time, resource);
clear_counters(time, resource);
+ // narrow array
+ start_counters(time, resource);
+ for (long i = 0; i < 20000000; ++i)
+ ct.narrow(bufwc, bufwc + sizeof(bufwc) / sizeof(wchar_t), '*', bufc);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "narrow array", time, resource);
+ clear_counters(time, resource);
+
// widen
start_counters(time, resource);
- for (long i = 0; i < iters; ++i)
+ for (long i = 0; i < 200000000; ++i)
ct.widen(i % 128);
stop_counters(time, resource);
report_performance(__FILE__, "widen", time, resource);
+ // widen array
+ start_counters(time, resource);
+ for (long i = 0; i < 20000000; ++i)
+ ct.widen(bufc, bufc + sizeof(bufc), bufwc);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "widen array", time, resource);
+
return 0;
}