OSDN Git Service

2003-12-12 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Dec 2003 19:44:17 +0000 (19:44 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Dec 2003 19:44:17 +0000 (19:44 +0000)
    Benjamin Kosnik  <bkoz@redhat.com>

PR libstdc++/13341
* include/bits/locale_facets.h (ctype<wchar_t>): Declare
_M_initialize_ctype() and _M_narrow_ok, _M_narrow and _M_widen.
* src/ctype.cc (ctype<wchar_t>::ctype(size_t),
ctype<wchar_t>::ctype(__c_locale, size_t)): Use
_M_initialize_ctype to fill _M_narrow and _M_widen.
(ctype_byname<wchar_t>::ctype_byname(const char*, size_t)):
Likewise.
* config/locale/generic/ctype_members.cc (do_narrow, do_widen)
Use _M_narrow and _M_widen when possible, instead of calling
wctob and btowc, respectively.
(_M_initialize_ctype): Define, it fills at construction time
_M_narrow and _M_widen.
* config/locale/gnu/ctype_members.cc: Likewise.
* testsuite/performance/narrow_widen_wchar_t.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74580 138bc75d-0d04-0410-961f-82ee72b054a4

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/src/ctype.cc
libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc [new file with mode: 0644]

index 8c5a764..27e23bf 100644 (file)
@@ -1,3 +1,22 @@
+2003-12-12  Paolo Carlini  <pcarlini@suse.de>
+           Benjamin Kosnik  <bkoz@redhat.com>
+
+       PR libstdc++/13341
+       * include/bits/locale_facets.h (ctype<wchar_t>): Declare
+       _M_initialize_ctype() and _M_narrow_ok, _M_narrow and _M_widen.
+       * src/ctype.cc (ctype<wchar_t>::ctype(size_t),
+       ctype<wchar_t>::ctype(__c_locale, size_t)): Use
+       _M_initialize_ctype to fill _M_narrow and _M_widen.
+       (ctype_byname<wchar_t>::ctype_byname(const char*, size_t)):
+       Likewise.
+       * config/locale/generic/ctype_members.cc (do_narrow, do_widen)
+       Use _M_narrow and _M_widen when possible, instead of calling
+       wctob and btowc, respectively.
+       (_M_initialize_ctype): Define, it fills at construction time
+       _M_narrow and _M_widen.
+       * config/locale/gnu/ctype_members.cc: Likewise.
+       * testsuite/performance/narrow_widen_wchar_t.cc: New.
+
 2003-12-12  Jonathan Wakely  <redi@gcc.gnu.org>
 
        * docs/html/faq/index.txt: Regenerate after adding <link> tags.
index 71175f1..517df4c 100644 (file)
@@ -185,7 +185,12 @@ namespace std
   wchar_t
   ctype<wchar_t>::
   do_widen(char __c) const
-  { return btowc(static_cast<unsigned char>(__c)); }
+  { 
+    const unsigned char __uc = static_cast<unsigned char>(__c);
+    if (__uc < 128)
+      return _M_widen[__uc];
+    return btowc(__uc);
+  }
   
   const char* 
   ctype<wchar_t>::
@@ -193,7 +198,11 @@ namespace std
   {
     while (__lo < __hi)
       {
-       *__dest = btowc(static_cast<unsigned char>(*__lo));
+       const unsigned char __uc = static_cast<unsigned char>(*__lo);   
+       if (__uc < 128)
+         *__dest = _M_widen[__uc];
+       else
+         *__dest = btowc(__uc);        
        ++__lo;
        ++__dest;
       }
@@ -204,7 +213,9 @@ namespace std
   ctype<wchar_t>::
   do_narrow(wchar_t __wc, char __dfault) const
   { 
-    int __c = wctob(__wc);
+    if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
+      return _M_narrow[__wc];
+    const int __c = wctob(__wc);
     return (__c == EOF ? __dfault : static_cast<char>(__c)); 
   }
 
@@ -213,14 +224,48 @@ namespace std
   do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 
            char* __dest) const
   {
-    while (__lo < __hi)
+    if (_M_narrow_ok)
+      while (__lo < __hi)
+       {
+         if (*__lo >= 0 && *__lo < 128)
+           *__dest = _M_narrow[*__lo];
+         else
+           {
+             const int __c = wctob(*__lo);
+             *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+           }
+         ++__lo;
+         ++__dest;
+       }
+    else
+      while (__lo < __hi)
+       {
+         const int __c = wctob(*__lo);
+         *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+         ++__lo;
+         ++__dest;
+       }
+    return __hi;
+  }
+
+  void
+  ctype<wchar_t>::_M_initialize_ctype()
+  {
+    wint_t __i;
+    for (__i = 0; __i < 128; ++__i)
       {
-       int __c = wctob(*__lo);
-       *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
-       ++__lo;
-       ++__dest;
+       const int __c = wctob(__i);
+       if (__c == EOF)
+         break;
+       else
+         _M_narrow[__i] = static_cast<char>(__c);
       }
-    return __hi;
+    if (__i == 128)
+      _M_narrow_ok = true;
+    else
+      _M_narrow_ok = false;
+    for (int __i = 0; __i < 128; ++__i)
+      _M_widen[__i] = btowc(__i);
   }
 #endif //  _GLIBCXX_USE_WCHAR_T
 }
index a5394b5..673b511 100644 (file)
@@ -192,14 +192,17 @@ namespace std
   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
-    wchar_t __ret = btowc(static_cast<unsigned char>(__c));
+    const wchar_t __wc = btowc(__uc);
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __uselocale(__old);
 #endif
-    return __ret;
+    return __wc;
   }
 
   const char* 
@@ -211,7 +214,11 @@ namespace std
 #endif
     while (__lo < __hi)
       {
-       *__dest = btowc(static_cast<unsigned char>(*__lo));
+       const unsigned char __uc = static_cast<unsigned char>(*__lo);   
+       if (__uc < 128)
+         *__dest = _M_widen[__uc];
+       else
+         *__dest = btowc(__uc);        
        ++__lo;
        ++__dest;
       }
@@ -225,10 +232,12 @@ namespace std
   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)
     __c_locale __old = __uselocale(_M_c_locale_ctype);
 #endif
-    int __c = wctob(__wc);
+    const int __c = wctob(__wc);
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __uselocale(__old);
 #endif
@@ -243,17 +252,57 @@ namespace std
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __c_locale __old = __uselocale(_M_c_locale_ctype);
 #endif
-    while (__lo < __hi)
+    if (_M_narrow_ok)
+      while (__lo < __hi)
+       {
+         if (*__lo >= 0 && *__lo < 128)
+           *__dest = _M_narrow[*__lo];
+         else
+           {
+             const int __c = wctob(*__lo);
+             *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+           }
+         ++__lo;
+         ++__dest;
+       }
+    else
+      while (__lo < __hi)
+       {
+         const int __c = wctob(*__lo);
+         *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
+         ++__lo;
+         ++__dest;
+       }
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+    __uselocale(__old);
+#endif
+    return __hi;
+  }
+
+  void
+  ctype<wchar_t>::_M_initialize_ctype()
+  {
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+    __c_locale __old = __uselocale(_M_c_locale_ctype);
+#endif
+    wint_t __i;
+    for (__i = 0; __i < 128; ++__i)
       {
-       int __c = wctob(*__lo);
-       *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
-       ++__lo;
-       ++__dest;
+       const int __c = wctob(__i);
+       if (__c == EOF)
+         break;
+       else
+         _M_narrow[__i] = static_cast<char>(__c);
       }
+    if (__i == 128)
+      _M_narrow_ok = true;
+    else
+      _M_narrow_ok = false;
+    for (int __i = 0; __i < 128; ++__i)
+      _M_widen[__i] = btowc(__i);
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
     __uselocale(__old);
 #endif
-    return __hi;
   }
 #endif //  _GLIBCXX_USE_WCHAR_T
 }
index a61ac9f..7a24b9b 100644 (file)
@@ -446,6 +446,11 @@ namespace std
     protected:
       __c_locale               _M_c_locale_ctype;
 
+      // Pre-computed narrowed and widened chars in the range 0-127.
+      bool                      _M_narrow_ok;      
+      char                      _M_narrow[128];
+      wint_t                    _M_widen[128];
+
     public:
       // Data Members:
       static locale::id                id;
@@ -500,6 +505,10 @@ namespace std
       virtual const char_type*
       do_narrow(const char_type* __lo, const char_type* __hi,
                char __dfault, char* __dest) const;
+
+      // For use at construction time only.
+      void 
+      _M_initialize_ctype();
     };
 
   template<>
index 7fb5c2d..b0888c5 100644 (file)
@@ -87,11 +87,17 @@ namespace std
 #ifdef _GLIBCXX_USE_WCHAR_T
   ctype<wchar_t>::ctype(size_t __refs) 
   : __ctype_abstract_base<wchar_t>(__refs)
-  { _M_c_locale_ctype = _S_get_c_locale(); }
+  { 
+    _M_c_locale_ctype = _S_get_c_locale();
+    _M_initialize_ctype();
+  }
 
   ctype<wchar_t>::ctype(__c_locale __cloc, size_t __refs) 
   : __ctype_abstract_base<wchar_t>(__refs) 
-  { _M_c_locale_ctype = _S_clone_c_locale(__cloc); }
+  {
+    _M_c_locale_ctype = _S_clone_c_locale(__cloc);
+    _M_initialize_ctype();
+  }
 
   ctype<wchar_t>::~ctype() 
   { _S_destroy_c_locale(_M_c_locale_ctype); }
@@ -103,7 +109,8 @@ namespace std
       if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
        {
          _S_destroy_c_locale(_M_c_locale_ctype);
-         _S_create_c_locale(_M_c_locale_ctype, __s); 
+         _S_create_c_locale(_M_c_locale_ctype, __s);
+         _M_initialize_ctype();
        }
     }
 #endif
diff --git a/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc b/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
new file mode 100644 (file)
index 0000000..1081bf5
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <locale>
+#include <testsuite_performance.h>
+
+int main()
+{
+  using namespace std;
+  using namespace __gnu_test;
+
+  time_counter time;
+  resource_counter resource;
+  const long iters = 200000000;
+
+  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)
+    ct.narrow(i % 128, '*');
+  stop_counters(time, resource);
+  report_performance(__FILE__, "narrow", time, resource);
+  clear_counters(time, resource);
+
+  // widen
+  start_counters(time, resource);
+  for (long i = 0; i < iters; ++i)
+    ct.widen(i % 128);
+  stop_counters(time, resource);
+  report_performance(__FILE__, "widen", time, resource);
+
+  return 0;
+}