aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2002-10-10 05:15:29 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2002-10-10 05:15:29 +0000
commit402a402cabeb85a223952f822eb14af6c3094a4c (patch)
tree7b9d08c6526562220c7bb210f6e6ce48283f90ea
parent7db40b5f9b8b4fd09fcd1409d083bada5fcb2a40 (diff)
downloadgcc-402a402cabeb85a223952f822eb14af6c3094a4c.zip
gcc-402a402cabeb85a223952f822eb14af6c3094a4c.tar.gz
gcc-402a402cabeb85a223952f822eb14af6c3094a4c.tar.bz2
locale.cc: Fix comments, move ctors together.
2002-10-09 Benjamin Kosnik <bkoz@redhat.com> * src/locale.cc: Fix comments, move ctors together. * testsuite/22_locale/static_members.cc (test03): Add. From-SVN: r58001
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/src/locale.cc41
-rw-r--r--libstdc++-v3/testsuite/22_locale/static_members.cc105
3 files changed, 119 insertions, 32 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 62ee709..5f1afaa 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2002-10-09 Benjamin Kosnik <bkoz@redhat.com>
+
+ * src/locale.cc: Fix comments, move ctors together.
+ * testsuite/22_locale/static_members.cc (test03): Add.
+
2002-10-08 Jonathan Lennox <lennox@cs.columbia.edu>
PR libstdc++/8071, libstdc++/8127, libstdc++/6745
diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc
index 641bee2..d9c6931 100644
--- a/libstdc++-v3/src/locale.cc
+++ b/libstdc++-v3/src/locale.cc
@@ -148,25 +148,6 @@ namespace std
0
};
- locale::~locale() throw()
- { _M_impl->_M_remove_reference(); }
-
- void
- locale::_M_coalesce(const locale& __base, const locale& __add,
- category __cat)
- {
- __cat = _S_normalize_category(__cat);
- _M_impl = new _Impl(*__base._M_impl, 1);
-
- try
- { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
- catch (...)
- {
- _M_impl->_M_remove_reference();
- __throw_exception_again;
- }
- }
-
locale::locale() throw()
{
_S_initialize();
@@ -178,6 +159,7 @@ namespace std
// This is used to initialize global and classic locales, and
// assumes that the _Impl objects are constructed correctly.
+ // The lack of a reference increment is intentional.
locale::locale(_Impl* __ip) throw() : _M_impl(__ip)
{ }
@@ -309,6 +291,9 @@ namespace std
locale::locale(const locale& __base, const locale& __add, category __cat)
{ _M_coalesce(__base, __add, __cat); }
+ locale::~locale() throw()
+ { _M_impl->_M_remove_reference(); }
+
bool
locale::operator==(const locale& __rhs) const throw()
{
@@ -381,7 +366,7 @@ namespace std
try
{
// 26 Standard facets, 2 references.
- // One reference for _M_classic, one for _M_global
+ // One reference for _S_classic, one for _S_global
_S_classic = new (&c_locale_impl) _Impl(0, 2, true);
_S_global = _S_classic;
new (&c_locale) locale(_S_classic);
@@ -399,6 +384,22 @@ namespace std
return c_locale;
}
+ void
+ locale::_M_coalesce(const locale& __base, const locale& __add,
+ category __cat)
+ {
+ __cat = _S_normalize_category(__cat);
+ _M_impl = new _Impl(*__base._M_impl, 1);
+
+ try
+ { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
+ catch (...)
+ {
+ _M_impl->_M_remove_reference();
+ __throw_exception_again;
+ }
+ }
+
locale::category
locale::_S_normalize_category(category __cat)
{
diff --git a/libstdc++-v3/testsuite/22_locale/static_members.cc b/libstdc++-v3/testsuite/22_locale/static_members.cc
index 06b1258..f8a9092 100644
--- a/libstdc++-v3/testsuite/22_locale/static_members.cc
+++ b/libstdc++-v3/testsuite/22_locale/static_members.cc
@@ -23,8 +23,7 @@
#include <cwchar> // for mbstate_t
#include <locale>
#include <iostream>
-//#include <testsuite_hooks.h>
-#define VERIFY(x) test &= x
+#include <testsuite_hooks.h>
typedef std::codecvt<char, char, std::mbstate_t> ccodecvt;
class gnu_codecvt: public ccodecvt { };
@@ -32,12 +31,11 @@ class gnu_codecvt: public ccodecvt { };
void test01()
{
using namespace std;
-
bool test = true;
+
string str1, str2;
// Construct a locale object with the C facet.
- const locale loc_env("");
const locale loc01 = locale::classic();
// Construct a locale object with the specialized facet.
@@ -54,13 +52,13 @@ void test01()
// global
locale loc03;
VERIFY ( loc03 == loc01);
- locale loc04 = locale::global(loc02);
+ locale global_orig = locale::global(loc02);
locale loc05;
VERIFY (loc05 != loc03);
VERIFY (loc05 == loc02);
- // Reset global locale.
- locale::global(loc_env);
+ // Reset global settings.
+ locale::global(global_orig);
}
// Sanity check locale::global(loc) and setlocale.
@@ -77,20 +75,102 @@ void test02()
// Get underlying current locale and environment settings.
const string lc_all_orig = std::setlocale(LC_ALL, NULL);
- const locale loc_orig("");
+ const locale env_orig("");
// setlocale to en_PH
string lc_all_ph = std::setlocale(LC_ALL, ph.c_str());
const locale loc_env("");
- VERIFY( loc_env == loc_orig );
+ VERIFY( loc_env == env_orig );
- locale::global(loc_mx);
+ locale global_orig = locale::global(loc_mx);
string lc_all_mx = std::setlocale(LC_ALL, NULL);
VERIFY( lc_all_mx == mx.c_str() );
- // Restore global info.
- locale::global(loc_orig);
+ // Restore global settings.
+ locale::global(global_orig);
+}
+
+// Static counter for use in checking ctors/dtors.
+static std::size_t counter;
+
+class surf : public std::locale::facet
+{
+public:
+ static std::locale::id id;
+ surf(size_t refs = 0): std::locale::facet(refs) { ++counter; }
+ ~surf() { --counter; }
+};
+
+std::locale::id surf::id;
+
+typedef surf facet_type;
+
+// Verify lifetimes of global objects.
+void test03()
+{
+ using namespace std;
+ bool test = true;
+
+ string name;
+ locale global_orig;
+ // 1: Destroyed when out of scope.
+ {
+ {
+ {
+ VERIFY( counter == 0 );
+ {
+ locale loc01(locale::classic(), new facet_type);
+ VERIFY( counter == 1 );
+ global_orig = locale::global(loc01);
+ name = loc01.name();
+ }
+ VERIFY( counter == 1 );
+ locale loc02 = locale();
+ // Weak, but it's something...
+ VERIFY( loc02.name() == name );
+ }
+ VERIFY( counter == 1 );
+ // NB: loc03 should be a copy of the previous global locale.
+ locale loc03 = locale::global(global_orig);
+ VERIFY( counter == 1 );
+ VERIFY( loc03.name() == name );
+ }
+ VERIFY( counter == 0 );
+ locale loc04 = locale();
+ VERIFY( loc04 == global_orig );
+ }
+
+ // 2: Not destroyed when out of scope, deliberately leaked.
+ {
+ {
+ {
+ VERIFY( counter == 0 );
+ {
+ locale loc01(locale::classic(), new facet_type(1));
+ VERIFY( counter == 1 );
+ global_orig = locale::global(loc01);
+ name = loc01.name();
+ }
+ VERIFY( counter == 1 );
+ locale loc02 = locale();
+ // Weak, but it's something...
+ VERIFY( loc02.name() == name );
+ }
+ VERIFY( counter == 1 );
+ // NB: loc03 should be a copy of the previous global locale.
+ locale loc03 = locale::global(global_orig);
+ VERIFY( counter == 1 );
+ VERIFY( loc03.name() == name );
+ }
+ VERIFY( counter == 1 );
+ locale loc04 = locale();
+ VERIFY( loc04 == global_orig );
+ }
+ VERIFY( counter == 1 );
+
+ // Restore global settings.
+ locale::global(global_orig);
}
int main ()
@@ -98,5 +178,6 @@ int main ()
test01();
test02();
+ test03();
return 0;
}