locale_facets.tcc (num_get::do_get(bool&)): Fail as soon as the begins of both truena...
authorPaolo Carlini <pcarlini@suse.de>
Mon, 15 Dec 2003 16:56:42 +0000 (16:56 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 15 Dec 2003 16:56:42 +0000 (16:56 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/config/locale/generic/ctype_members.cc
libstdc++-v3/config/locale/gnu/ctype_members.cc
libstdc++-v3/include/bits/locale_facets.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/22_locale/num_get/get/char/8.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/8.cc [new file with mode: 0644]
libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc

index 27e23bf54820693cec7140c1a053b5d58bb2fa55..e0f17c36b839434858c37adafd2eada8e1c88f38 100644 (file)
@@ -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>
 
index 517df4c21875253fde9be717a2715814ca02328a..e94d447a251cea1a9ef835a903bcaf3965aaa5d8 100644 (file)
@@ -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
index 673b511e5cd171c9cda412c24abf4ced4aa0e823..998737b273d9f4789699f08f340329dafc3ece7b 100644 (file)
@@ -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);
index 7a24b9b30fe92ffc50766e8efbdd225de69d6813..83d77c81119f8937f2b14bd4d0c8e7bf77d9e407 100644 (file)
@@ -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:
index a583e0e07baf4f5042b8766b8779d194eee0bc01..84f0b887852da5e1b7c70d328fd152d9df347885 100644 (file)
@@ -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 (file)
index 0000000..d3f24f9
--- /dev/null
@@ -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 (file)
index 0000000..fbba3a5
--- /dev/null
@@ -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;
+}
index 1081bf564526f967728925c8f4fc14bf7d6ba62d..053f807261069abbb5f2f9a5c6115aec642364ec 100644 (file)
@@ -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;
 }