summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/22_locale/numpunct
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-10 06:21:13 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-10 06:21:13 +0000
commita08fc974d0aca9ebe425b3a6478c55836fa88218 (patch)
tree94aee28a3995a67905d614532af5c300830ca624 /libstdc++-v3/testsuite/22_locale/numpunct
parent0e32b25538b63f75c80e55db28852d86324680f2 (diff)
downloadgcc-a08fc974d0aca9ebe425b3a6478c55836fa88218.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69177 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/testsuite/22_locale/numpunct')
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_1.cc78
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_2.cc90
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc134
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc267
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc78
-rw-r--r--libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc90
6 files changed, 737 insertions, 0 deletions
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
index 00000000000..002b0c47e37
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_1.cc
@@ -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
index 00000000000..729e82a64bd
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/char/cache_2.cc
@@ -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
index 00000000000..c0cf534af7b
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc
@@ -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
index 00000000000..32b26eda0cd
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc
@@ -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
index 00000000000..0b41e963f50
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc
@@ -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
index 00000000000..9a3c4872e5c
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc
@@ -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;
+}