OSDN Git Service

2003-07-09 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Jul 2003 06:21:13 +0000 (06:21 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Jul 2003 06:21:13 +0000 (06:21 +0000)
* include/bits/locale_facets.tcc: Use function object for
__use_cache instead of template function. Partially specialize for
__numpunct<_CharT>.
* include/bits/locale_classes.h: Update friend declaration for
__use_cache.
(_M_install_cache): No throw exception specs.
* src/locale.cc: Remove __use_cache specializations.
* include/ext/pod_char_traits.h (length): Tweak.
* include/bits/locale_facets.h (__numpunct_cache): Remove
char_type typedef.
* testsuite/testsuite_hooks.h (pod_unsigned_int): Remove.
(pod_long): Remove.
* testsuite/22_locale/numpunct/members/char/cache_1.cc: New.
* testsuite/22_locale/numpunct/members/char/cache_2.cc: New.
* testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc: New.
* testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc: New.
* testsuite/22_locale/numpunct/members/pod/1.cc: New.
* testsuite/22_locale/numpunct/members/pod/2.cc: New.

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

13 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/locale_facets.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/include/ext/pod_char_traits.h
libstdc++-v3/src/locale.cc
libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/testsuite_hooks.h

index b5c970e..885f9b2 100644 (file)
@@ -1,3 +1,24 @@
+2003-07-09  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * include/bits/locale_facets.tcc: Use function object for
+       __use_cache instead of template function. Partially specialize for 
+       __numpunct<_CharT>.
+       * include/bits/locale_classes.h: Update friend declaration for
+       __use_cache.
+       (_M_install_cache): No throw exception specs.
+       * src/locale.cc: Remove __use_cache specializations.
+       * include/ext/pod_char_traits.h (length): Tweak.
+       * include/bits/locale_facets.h (__numpunct_cache): Remove
+       char_type typedef.
+       * testsuite/testsuite_hooks.h (pod_unsigned_int): Remove.
+       (pod_long): Remove.
+       * testsuite/22_locale/numpunct/members/char/cache_1.cc: New.
+       * testsuite/22_locale/numpunct/members/char/cache_2.cc: New.
+       * testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc: New.
+       * testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc: New.
+       * testsuite/22_locale/numpunct/members/pod/1.cc: New.
+       * testsuite/22_locale/numpunct/members/pod/2.cc: New.
+       
 2003-07-09  Jerry Quinn  <jlquinn@optonline.net>
 
        * src/ios.cc (_M_grow_words):  Fix spelling.
index 362e38f..b93cfb3 100644 (file)
@@ -73,8 +73,7 @@ namespace std
       use_facet(const locale&);
 
     template<typename _Cache>
-      friend const _Cache&
-      __use_cache(const locale& __loc);
+      friend struct __use_cache;
    
     // Category values:
     // NB: Order must match _S_facet_categories definition in locale.cc
@@ -298,8 +297,7 @@ namespace std
       use_facet(const locale&);
 
     template<typename _Cache>
-      friend const _Cache&
-      __use_cache(const locale& __loc);
+      friend struct __use_cache;
 
   private:
     // Data Members.
@@ -370,7 +368,7 @@ namespace std
       { _M_install_facet(&_Facet::id, __facet); }
 
     void
-    _M_install_cache(const facet* __cache, size_t __index)
+    _M_install_cache(const facet* __cache, size_t __index) throw()
     { 
       __cache->_M_add_reference();
       _M_caches[__index] = __cache; 
index 6b5a99d..cda0dcb 100644 (file)
@@ -577,34 +577,31 @@ namespace std
   template<typename _CharT>
     struct __numpunct_cache : public locale::facet
     {
-      // Types:
-      typedef _CharT                   char_type;
-
       const char*                      _M_grouping;
       bool                             _M_use_grouping;
-      const char_type*                         _M_truename;
-      const char_type*                 _M_falsename;
-      char_type                        _M_decimal_point;
-      char_type                        _M_thousands_sep;
+      const _CharT*                    _M_truename;
+      const _CharT*                    _M_falsename;
+      _CharT                           _M_decimal_point;
+      _CharT                           _M_thousands_sep;
       
       // A list of valid numeric literals for output: in the standard
       // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
       // This array contains the chars after having been passed
       // through the current locale's ctype<_CharT>.widen().
-      char_type                        _M_atoms_out[__num_base::_S_oend + 1];
+      _CharT                           _M_atoms_out[__num_base::_S_oend + 1];
 
       // A list of valid numeric literals for output: in the standard
       // "C" locale, this is "0123456789eEabcdfABCDF"
       // This array contains the chars after having been passed
       // through the current locale's ctype<_CharT>.widen().
-      char_type                        _M_atoms_in[__num_base::_S_iend + 1];
+      _CharT                           _M_atoms_in[__num_base::_S_iend + 1];
 
       bool                             _M_allocated;
 
       __numpunct_cache(size_t __refs = 0) : locale::facet(__refs), 
       _M_grouping(NULL), _M_use_grouping(false), _M_truename(NULL), 
-      _M_falsename(NULL), _M_decimal_point(char_type()), 
-      _M_thousands_sep(char_type()), _M_allocated(false)
+      _M_falsename(NULL), _M_decimal_point(_CharT()), 
+      _M_thousands_sep(_CharT()), _M_allocated(false)
       { } 
 
       ~__numpunct_cache();
index 97cec3f..d41b8ae 100644 (file)
@@ -89,18 +89,38 @@ namespace std
   // Routine to access a cache for the facet.  If the cache didn't
   // exist before, it gets constructed on the fly.
   template<typename _Facet>
-    const _Facet&
-    __use_cache(const locale& __loc);
-
-  template<>
-    const __numpunct_cache<char>&
-    __use_cache(const locale& __loc);
+    struct __use_cache
+    {
+      const _Facet*
+      operator() (const locale& __loc) const;
+    };
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    const __numpunct_cache<wchar_t>&
-    __use_cache(const locale& __loc);
-#endif
+  template<typename _CharT>
+    struct __use_cache<__numpunct_cache<_CharT> >
+    {
+      const __numpunct_cache<_CharT>*
+      operator() (const locale& __loc) const
+      {
+       size_t __i = numpunct<_CharT>::id._M_id();
+       const locale::facet** __caches = __loc._M_impl->_M_caches;
+       if (!__caches[__i])
+         {
+           __numpunct_cache<_CharT>* __tmp;
+           try
+             {
+               __tmp = new __numpunct_cache<_CharT>;
+               __tmp->_M_cache(__loc);
+             }
+           catch(...)
+             {
+               delete __tmp;
+               __throw_exception_again;
+             }
+           __loc._M_impl->_M_install_cache(__tmp, __i);
+         }
+       return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
+      }
+    };
 
   // Stage 1: Determine a conversion specifier.
   template<typename _CharT, typename _InIter>
@@ -785,9 +805,10 @@ namespace std
                     _ValueT __v) const
       {
        typedef typename numpunct<_CharT>::__cache_type  __cache_type;
+       __use_cache<__cache_type> __uc;
        const locale& __loc = __io._M_getloc();
-       const __cache_type& __lc = __use_cache<__cache_type>(__loc);
-       const _CharT* __lit = __lc._M_atoms_out;
+       const __cache_type* __lc = __uc(__loc);
+       const _CharT* __lit = __lc->_M_atoms_out;
 
        // Long enough to hold hex, dec, and octal representations.
        int __ilen = 4 * sizeof(_ValueT);
@@ -801,13 +822,13 @@ namespace std
        
        // Add grouping, if necessary. 
        _CharT* __cs2;
-       if (__lc._M_use_grouping)
+       if (__lc->_M_use_grouping)
          {
            // Grouping can add (almost) as many separators as the
            // number of digits, but no more.
            __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
                                                          * __len * 2));
-           _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io, 
+           _M_group_int(__lc->_M_grouping, __lc->_M_thousands_sep, __io, 
                         __cs2, __cs, __len);
            __cs = __cs2;
          }
@@ -890,8 +911,9 @@ namespace std
          __prec = static_cast<streamsize>(6);
 
        typedef typename numpunct<_CharT>::__cache_type  __cache_type;
+       __use_cache<__cache_type> __uc;
        const locale& __loc = __io._M_getloc();
-       const __cache_type& __lc = __use_cache<__cache_type>(__loc);
+       const __cache_type* __lc = __uc(__loc);
 
        // [22.2.2.2.2] Stage 1, numeric conversion to character.
        int __len;
@@ -944,20 +966,20 @@ namespace std
       
       // Replace decimal point.
       const _CharT __cdec = __ctype.widen('.');
-      const _CharT __dec = __lc._M_decimal_point;
+      const _CharT __dec = __lc->_M_decimal_point;
       const _CharT* __p;
       if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
        __ws[__p - __ws] = __dec;
 
       // Add grouping, if necessary. 
       _CharT* __ws2;
-      if (__lc._M_use_grouping)
+      if (__lc->_M_use_grouping)
        {
            // Grouping can add (almost) as many separators as the
            // number of digits, but no more.
            __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
                                                          * __len * 2));
-           _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p,
+           _M_group_float(__lc->_M_grouping, __lc->_M_thousands_sep, __p,
                           __ws2, __ws, __len);
            __ws = __ws2;
        }
@@ -992,15 +1014,16 @@ namespace std
       else
         {
          typedef typename numpunct<_CharT>::__cache_type  __cache_type;
+         __use_cache<__cache_type> __uc;
          const locale& __loc = __io._M_getloc();
-         const __cache_type& __lc = __use_cache<__cache_type>(__loc);
+         const __cache_type* __lc = __uc(__loc);
 
          typedef basic_string<_CharT>  __string_type;
          __string_type __name;
           if (__v)
-           __name = __lc._M_truename;
+           __name = __lc->_M_truename;
           else
-           __name = __lc._M_falsename;
+           __name = __lc->_M_falsename;
 
          const _CharT* __cs = __name.c_str();
          int __len = __name.size();
@@ -1339,7 +1362,8 @@ namespace std
       // decimal digit, '\0'. 
       const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-      int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
+      int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units, 
+                                       _S_c_locale);
 #endif
       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
                                                           * __cs_size));
@@ -2280,8 +2304,8 @@ namespace std
     {
       if (__last - __first > *__gbeg)
         {
-          __s = std::__add_grouping(__s,  __sep, 
-                                   (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
+         const bool __bump = __gbeg + 1 != __gend;
+          __s = std::__add_grouping(__s,  __sep, __gbeg + __bump,
                                    __gend, __first, __last - *__gbeg);
           __first = __last - *__gbeg;
           *__s++ = __sep;
index 0de7a0f..0145a48 100644 (file)
@@ -98,7 +98,7 @@ namespace std
       length(const char_type* __s)
       { 
        const char_type* __p = __s; 
-       while (*__p
+       while (__p->value
          ++__p; 
        return (__p - __s); 
       }
index 248fdf3..43f831d 100644 (file)
@@ -451,38 +451,6 @@ namespace std
   locale::facet::
   ~facet() { }
 
-  template<>
-    const __numpunct_cache<char>&
-    __use_cache(const locale& __loc)
-    {
-      size_t __i = numpunct<char>::id._M_id();
-      const locale::facet** __caches = __loc._M_impl->_M_caches;
-      if (!__caches[__i])
-       {
-         __numpunct_cache<char>* __tmp = new __numpunct_cache<char>;
-         __tmp->_M_cache(__loc);
-         __loc._M_impl->_M_install_cache(__tmp, __i);
-       }
-      return static_cast<const __numpunct_cache<char>&>(*__caches[__i]);
-    }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    const __numpunct_cache<wchar_t>&
-    __use_cache(const locale& __loc)
-    {
-      size_t __i = numpunct<wchar_t>::id._M_id();
-      const locale::facet** __caches = __loc._M_impl->_M_caches;
-      if (!__caches[__i])
-       {
-         __numpunct_cache<wchar_t>* __tmp = new __numpunct_cache<wchar_t>;
-         __tmp->_M_cache(__loc);
-         __loc._M_impl->_M_install_cache(__tmp, __i);
-       }
-      return static_cast<const __numpunct_cache<wchar_t>&>(*__caches[__i]);
-    }
-#endif
-
   // Definitions for static const data members of time_base.
   template<> 
     const char*
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_1.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_1.cc
new file mode 100644 (file)
index 0000000..002b0c4
--- /dev/null
@@ -0,0 +1,78 @@
+// 2003-07-06  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <testsuite_hooks.h>
+
+class numpunct_checked : public std::numpunct<char>
+{
+  typedef std::numpunct<char> base;
+
+public:
+  explicit 
+  numpunct_checked(std::size_t refs = 0): base(refs) { }
+
+  string_type
+  base_truename() const
+  { return base::do_truename(); }
+
+protected:
+  virtual string_type  
+  do_truename() const
+  { return base::do_truename() + "st"; }
+};
+
+// Thwart locale caching strategies that incorrectly overwrite base
+// class data.
+void test01()
+{
+  using namespace std;
+
+  bool                 test = true;
+  const string         basestr("true");
+  const string         derivedstr("truest");
+
+  const locale         loc(locale::classic(), new numpunct_checked);   
+  stringbuf    sbuf;
+  ostream      os(&sbuf);
+  os.setf(ios_base::boolalpha);
+
+  // Pre-cache sanity check.
+  const numpunct<char>& np = use_facet<numpunct<char> >(loc);
+  VERIFY( np.truename() == derivedstr );
+  
+  // Cache.
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Post-cache sanity check, make sure that base class is still fine.
+  VERIFY( np.truename() == derivedstr );
+  const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
+  VERIFY( npd.base_truename() == basestr );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_2.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_2.cc
new file mode 100644 (file)
index 0000000..729e82a
--- /dev/null
@@ -0,0 +1,90 @@
+// 2003-07-06  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <testsuite_hooks.h>
+
+class numpunct_checked : public std::numpunct<char>
+{
+  typedef std::numpunct<char> base;
+
+public:
+  explicit 
+  numpunct_checked(std::size_t refs = 0): base(refs) { }
+
+  string_type
+  base_truename() const
+  { return base::do_truename(); }
+
+protected:
+  virtual string_type  
+  do_truename() const
+  { return base::do_truename() + "st"; }
+};
+
+// Changing caches deletes old cache, adds new one.
+void test01()
+{
+  using namespace std;
+
+  bool                 test = true;
+  const string         empty;
+  const string         basestr("true");
+  const string         derivedstr("truest");
+
+  const locale         loc(locale::classic(), new numpunct_checked);   
+  stringbuf    sbuf;
+  ostream      os(&sbuf);
+  os.setf(ios_base::boolalpha);
+
+  // Pre-cache sanity check.
+  const numpunct<char>& np = use_facet<numpunct<char> >(loc);
+  VERIFY( np.truename() == derivedstr );
+  
+  // Cache.
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Re-cache.
+  sbuf.str(empty);
+  os.imbue(locale::classic());
+  os << true;
+  VERIFY( sbuf.str() == basestr );
+
+  // Cache new locale again.
+  sbuf.str(empty);
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Post-cache sanity check, make sure that base class is still fine.
+  VERIFY( np.truename() == derivedstr );
+  const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
+  VERIFY( npd.base_truename() == basestr );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc
new file mode 100644 (file)
index 0000000..c0cf534
--- /dev/null
@@ -0,0 +1,134 @@
+// 2003-07-09  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <stdexcept>
+#include <ext/pod_char_traits.h>
+#include <testsuite_hooks.h>
+
+typedef unsigned short                                 value_type;
+typedef unsigned int                                   int_type;
+typedef __gnu_cxx::character<value_type, int_type>     podchar_type;
+
+// Member specializations for the existing facet classes.
+// NB: This isn't especially portable. Perhaps a better way would be
+// to just specialize all of numpunct and ctype.
+namespace std
+{
+  template<>
+    void
+    numpunct<podchar_type>::_M_initialize_numpunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+       _M_data = new __numpunct_cache<podchar_type>;
+
+      _M_data->_M_grouping = "";
+      _M_data->_M_use_grouping = false;
+
+      _M_data->_M_decimal_point.value =  value_type('.');
+      _M_data->_M_thousands_sep.value = value_type(',');
+      
+      for (size_t i = 0; i < __num_base::_S_oend; ++i)
+       {
+         value_type v = __num_base::_S_atoms_out[i];
+         _M_data->_M_atoms_out[i].value = v;
+       }
+      _M_data->_M_atoms_out[__num_base::_S_oend] = podchar_type();
+      
+      for (size_t i = 0; i < __num_base::_S_iend; ++i)
+       _M_data->_M_atoms_in[i].value = value_type(__num_base::_S_atoms_in[i]);
+      _M_data->_M_atoms_in[__num_base::_S_iend] = podchar_type();
+
+      // "true"
+      podchar_type* __truename = new podchar_type[4 + 1];
+      __truename[0].value = value_type('t');
+      __truename[1].value = value_type('r');
+      __truename[2].value = value_type('u');
+      __truename[3].value = value_type('e');
+      __truename[4] = podchar_type();
+      _M_data->_M_truename = __truename;
+
+      // "false"
+      podchar_type* __falsename = new podchar_type[5 + 1];
+      __falsename[0].value = value_type('f');
+      __falsename[1].value = value_type('a');
+      __falsename[2].value = value_type('l');
+      __falsename[3].value = value_type('s');
+      __falsename[4].value = value_type('e');
+      __falsename[5] = podchar_type();
+      _M_data->_M_falsename = __falsename;
+    }
+
+  template<>
+    numpunct<podchar_type>::~numpunct()
+    { delete _M_data; }
+}
+
+// Check for numpunct and ctype dependencies. Make sure that numpunct
+// can be created without ctype.
+void test01()
+{
+  using namespace std;
+  typedef numpunct<podchar_type>::string_type  string_type;
+  typedef basic_stringbuf<podchar_type>        stringbuf_type;
+  typedef basic_ostream<podchar_type>          ostream_type;
+  
+  bool                 test = true;
+
+  // Pre-cache sanity check.
+  const locale         loc(locale::classic(), new numpunct<podchar_type>);
+  const numpunct<podchar_type>& np = use_facet<numpunct<podchar_type> >(loc);
+
+  podchar_type dp = np.decimal_point();
+  podchar_type ts = np.thousands_sep();
+  string g = np.grouping();
+  string_type strue = np.truename();
+  string_type sfalse = np.falsename();
+
+  podchar_type basedp = { value_type('.') };
+  podchar_type basets = { value_type(',') };
+
+  string_type basetrue(4, podchar_type());
+  basetrue[0].value = value_type('t');
+  basetrue[1].value = value_type('r');
+  basetrue[2].value = value_type('u');
+  basetrue[3].value = value_type('e');
+
+  string_type basefalse(5, podchar_type());
+  basefalse[0].value = value_type('f');
+  basefalse[1].value = value_type('a');
+  basefalse[2].value = value_type('l');
+  basefalse[3].value = value_type('s');
+  basefalse[4].value = value_type('e');
+
+  VERIFY( char_traits<podchar_type>::eq(dp, basedp) );
+  VERIFY( char_traits<podchar_type>::eq(ts, basets) );
+  VERIFY( g == "" );
+  VERIFY( strue == basetrue );
+  VERIFY( sfalse == basefalse );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc
new file mode 100644 (file)
index 0000000..32b26ed
--- /dev/null
@@ -0,0 +1,267 @@
+// 2003-07-09  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <stdexcept>
+#include <ext/pod_char_traits.h>
+#include <testsuite_hooks.h>
+
+typedef unsigned short                                 value_type;
+typedef unsigned int                                   int_type;
+typedef __gnu_cxx::character<value_type, int_type>     podchar_type;
+
+// Member specializations for the existing facet classes.
+// NB: This isn't especially portable. Perhaps a better way would be
+// to just specialize all of numpunct and ctype.
+namespace std
+{
+  template<>
+    bool 
+    ctype<podchar_type>::
+    do_is(mask __m, char_type __c) const { return true; }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const
+    { return __lo; }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
+    { return __lo; }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
+    { return __lo; }
+
+  template<>
+    podchar_type 
+    ctype<podchar_type>::
+    do_toupper(char_type __c) const
+    { return __c; }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_toupper(char_type* __lo, const char_type* __hi) const
+    { return __hi; }
+
+  template<>
+    podchar_type 
+    ctype<podchar_type>::
+    do_tolower(char_type __c) const
+    { return __c; }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_tolower(char_type* __lo, const char_type* __hi) const
+    { return __hi; }
+
+  template<>
+    podchar_type
+    ctype<podchar_type>::
+    do_widen(char __c) const
+    { 
+      char_type ret = { value_type(__c) };
+      return ret;
+    }
+
+  template<>
+    const char*
+    ctype<podchar_type>::
+    do_widen(const char* __lo, const char* __hi, char_type* __dest) const
+    {
+      while (__lo < __hi)
+       {
+         *__dest = this->do_widen(*__lo);
+         ++__lo;
+         ++__dest;
+       }
+      return __hi;
+    }
+
+  template<>
+    char
+    ctype<podchar_type>::
+    do_narrow(char_type __wc, char) const
+    { return static_cast<char>(__wc.value); }
+
+  template<>
+    const podchar_type*
+    ctype<podchar_type>::
+    do_narrow(const podchar_type* __lo, const podchar_type* __hi, 
+             char __dfault, char* __dest) const
+    {
+      while (__lo < __hi)
+       {
+         *__dest = this->do_narrow(*__lo, char());
+         ++__lo;
+         ++__dest;
+       }
+      return __hi;
+    }
+
+  template<>
+    ctype<podchar_type>::~ctype() { }
+
+  template<>
+    void
+    numpunct<podchar_type>::_M_initialize_numpunct(__c_locale __cloc)
+    {
+      if (!_M_data)
+       _M_data = new __numpunct_cache<podchar_type>;
+
+      _M_data->_M_grouping = "";
+      _M_data->_M_use_grouping = false;
+
+      _M_data->_M_decimal_point.value =  value_type('.');
+      _M_data->_M_thousands_sep.value = value_type(',');
+      
+      for (size_t i = 0; i < __num_base::_S_oend; ++i)
+       {
+         value_type v = __num_base::_S_atoms_out[i];
+         _M_data->_M_atoms_out[i].value = v;
+       }
+      _M_data->_M_atoms_out[__num_base::_S_oend] = podchar_type();
+      
+      for (size_t i = 0; i < __num_base::_S_iend; ++i)
+       _M_data->_M_atoms_in[i].value = value_type(__num_base::_S_atoms_in[i]);
+      _M_data->_M_atoms_in[__num_base::_S_iend] = podchar_type();
+
+      // "true"
+      podchar_type* __truename = new podchar_type[4 + 1];
+      __truename[0].value = value_type('t');
+      __truename[1].value = value_type('r');
+      __truename[2].value = value_type('u');
+      __truename[3].value = value_type('e');
+      __truename[4] = podchar_type();
+      _M_data->_M_truename = __truename;
+
+      // "false"
+      podchar_type* __falsename = new podchar_type[5 + 1];
+      __falsename[0].value = value_type('f');
+      __falsename[1].value = value_type('a');
+      __falsename[2].value = value_type('l');
+      __falsename[3].value = value_type('s');
+      __falsename[4].value = value_type('e');
+      __falsename[5] = podchar_type();
+      _M_data->_M_falsename = __falsename;
+    }
+
+  template<>
+    numpunct<podchar_type>::~numpunct()
+    { delete _M_data; }
+}
+
+// Check for numpunct and ctype dependencies. Make sure that numpunct
+// can be created without ctype.
+void test01()
+{
+  using namespace std;
+  typedef numpunct<podchar_type>::string_type  string_type;
+  typedef basic_ostringstream<podchar_type>            ostream_type;
+  
+  bool                 test = true;
+
+  // Test formatted output.
+  ostream_type                 os;
+  const locale         loc = locale::classic();
+  os.imbue(loc);
+  os.setf(ios_base::boolalpha);
+  os.exceptions(ios_base::badbit);
+
+  // 1: fail, no num_put.
+  try
+    {
+      // Calls to num_put.put will fail, as there's no num_put facet.
+      os << true;
+      test = false;
+    }
+  catch(const bad_cast& obj)
+    { }
+  catch(...)
+    { test = false; }
+  VERIFY( test );
+
+  // 2: fail, no ctype
+  const locale         loc2(loc, new num_put<podchar_type>);
+  os.clear();
+  os.imbue(loc2);
+  try
+    {
+      // Calls to ctype.widen will fail, as there's no ctype facet.
+      os << true;
+      test = false;
+    }
+  catch(const bad_cast& obj)
+    { }
+  catch(...)
+    { test = false; }
+  VERIFY( test );
+
+  // 3: fail, no numpunct
+  const locale         loc3(loc, new ctype<podchar_type>);
+  os.clear();
+  os.imbue(loc3);
+  try
+    {
+      // Formatted output fails as no numpunct.
+      os << true;
+      test = false;
+    }
+  catch(const bad_cast& obj)
+    { }
+  catch(...)
+    { test = false; }
+  VERIFY( test );
+
+  // 4: works.
+  const locale         loc4(loc3, new numpunct<podchar_type>);
+  os.clear();
+  os.imbue(loc4);
+  try
+    {
+      os << long(500);
+      string_type s = os.str();
+      VERIFY( s.length() == 3 );
+
+      VERIFY( os.narrow(s[0], char()) == '5' );
+      VERIFY( os.narrow(s[1], char()) == '0' );
+      VERIFY( os.narrow(s[2], char()) == '0' );
+    }
+  catch(const bad_cast& obj)
+    { test = false; }
+  catch(...)
+    { test = false; }
+  VERIFY( test );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc
new file mode 100644 (file)
index 0000000..0b41e96
--- /dev/null
@@ -0,0 +1,78 @@
+// 2003-07-06  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <testsuite_hooks.h>
+
+class numpunct_checked : public std::numpunct<wchar_t>
+{
+  typedef std::numpunct<wchar_t> base;
+
+public:
+  explicit 
+  numpunct_checked(std::size_t refs = 0): base(refs) { }
+
+  string_type
+  base_truename() const
+  { return base::do_truename(); }
+
+protected:
+  virtual string_type  
+  do_truename() const
+  { return base::do_truename() + L"st"; }
+};
+
+// Thwart locale caching strategies that incorrectly overwrite base
+// class data.
+void test01()
+{
+  using namespace std;
+
+  bool                 test = true;
+  const wstring        basestr(L"true");
+  const wstring        derivedstr(L"truest");
+
+  const locale         loc(locale::classic(), new numpunct_checked);   
+  wstringbuf   sbuf;
+  wostream     os(&sbuf);
+  os.setf(ios_base::boolalpha);
+
+  // Pre-cache sanity check.
+  const numpunct<wchar_t>& np = use_facet<numpunct<wchar_t> >(loc);
+  VERIFY( np.truename() == derivedstr );
+  
+  // Cache.
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Post-cache sanity check, make sure that base class is still fine.
+  VERIFY( np.truename() == derivedstr );
+  const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
+  VERIFY( npd.base_truename() == basestr );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc b/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc
new file mode 100644 (file)
index 0000000..9a3c487
--- /dev/null
@@ -0,0 +1,90 @@
+// 2003-07-06  Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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.
+
+#include <locale>
+#include <sstream>
+#include <ostream>
+#include <testsuite_hooks.h>
+
+class numpunct_checked : public std::numpunct<wchar_t>
+{
+  typedef std::numpunct<wchar_t> base;
+
+public:
+  explicit 
+  numpunct_checked(std::size_t refs = 0): base(refs) { }
+
+  string_type
+  base_truename() const
+  { return base::do_truename(); }
+
+protected:
+  virtual string_type  
+  do_truename() const
+  { return base::do_truename() + L"st"; }
+};
+
+// Changing caches deletes old cache, adds new one.
+void test01()
+{
+  using namespace std;
+
+  bool                 test = true;
+  const wstring        empty;
+  const wstring        basestr(L"true");
+  const wstring        derivedstr(L"truest");
+
+  const locale         loc(locale::classic(), new numpunct_checked);   
+  wstringbuf   sbuf;
+  wostream     os(&sbuf);
+  os.setf(ios_base::boolalpha);
+
+  // Pre-cache sanity check.
+  const numpunct<wchar_t>& np = use_facet<numpunct<wchar_t> >(loc);
+  VERIFY( np.truename() == derivedstr );
+  
+  // Cache.
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Re-cache.
+  sbuf.str(empty);
+  os.imbue(locale::classic());
+  os << true;
+  VERIFY( sbuf.str() == basestr );
+
+  // Cache new locale again.
+  sbuf.str(empty);
+  os.imbue(loc);
+  os << true;
+  VERIFY( sbuf.str() == derivedstr );
+
+  // Post-cache sanity check, make sure that base class is still fine.
+  VERIFY( np.truename() == derivedstr );
+  const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
+  VERIFY( npd.base_truename() == basestr );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
index 896bf1c..5de881a 100644 (file)
@@ -127,16 +127,6 @@ namespace __gnu_cxx_test
     int i;
   };
   
-  struct pod_unsigned_int
-  {
-    unsigned int i;
-  };
-  
-  struct pod_long
-  {
-    unsigned long i;
-  };
-  
   struct state
   {
     unsigned long l;