locale_facets.tcc (locale::combine): Clone _Impl.

2001-06-29  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/locale_facets.tcc (locale::combine): Clone _Impl.
	before replacing facet.
	* include/bits/localefwd.h (locale::_Impl::_M_remove_reference):
	Correct decrement.
	* src/localename.cc (locale::_Impl): Correct ctor initialization
	lists. Initialize ref count with one. Simplify.
	* src/locale.cc: Add comment.
	* testsuite/22_locale/numpunct.cc (test01): Add derivation test.
	* testsuite/22_locale/numpunct_char_members.cc (test01): Add tests.
	* testsuite/22_locale/members.cc (test02): Fix.

From-SVN: r43661
This commit is contained in:
Benjamin Kosnik 2001-06-30 04:35:49 +00:00 committed by Benjamin Kosnik
parent 8f1ae09ac2
commit 13f83598b3
8 changed files with 95 additions and 53 deletions

View File

@ -1,3 +1,16 @@
2001-06-29 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/locale_facets.tcc (locale::combine): Clone _Impl.
before replacing facet.
* include/bits/localefwd.h (locale::_Impl::_M_remove_reference):
Correct decrement.
* src/localename.cc (locale::_Impl): Correct ctor initialization
lists. Initialize ref count with one. Simplify.
* src/locale.cc: Add comment.
* testsuite/22_locale/numpunct.cc (test01): Add derivation test.
* testsuite/22_locale/numpunct_char_members.cc (test01): Add tests.
* testsuite/22_locale/members.cc (test02): Fix.
2001-06-27 Phil Edwards <pme@sources.redhat.com> 2001-06-27 Phil Edwards <pme@sources.redhat.com>
* include/backward/algo.h: Add "GPL plus runtime exception" comment * include/backward/algo.h: Add "GPL plus runtime exception" comment
@ -81,7 +94,7 @@
* src/bitset.cc: Likewise. * src/bitset.cc: Likewise.
* src/strstream.cc: Likewise. * src/strstream.cc: Likewise.
2001-06-26 Benjamin Kosnik <bkoz@fillmore.constant.com> 2001-06-26 Benjamin Kosnik <bkoz@redhat.com>
<vakatov@ncbi.nlm.nih.gov> <vakatov@ncbi.nlm.nih.gov>
libstdc++/3272 libstdc++/3272

View File

@ -42,16 +42,15 @@
#include <typeinfo> // For bad_cast #include <typeinfo> // For bad_cast
#include <bits/std_vector.h> #include <bits/std_vector.h>
namespace std namespace std
{ {
template<typename _Facet> template<typename _Facet>
locale locale
locale::combine(const locale& __other) locale::combine(const locale& __other)
{ {
locale __copy(*this); _Impl* __tmp = new _Impl(*_M_impl, 1);
__copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id); __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
return __copy; return locale(__tmp);
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>

View File

@ -326,7 +326,7 @@ namespace std
inline void inline void
_M_remove_reference() throw() _M_remove_reference() throw()
{ {
if (_M_references-- == 0) // XXX MT if (--_M_references == 0) // XXX MT
{ {
try try
{ delete this; } { delete this; }

View File

@ -362,6 +362,7 @@ namespace std
locale::locale(const locale& __other) throw() locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); } { (_M_impl = __other._M_impl)->_M_add_reference(); }
// This is used to initialize global and classic locales.
locale::locale(_Impl* __ip) throw() locale::locale(_Impl* __ip) throw()
: _M_impl(__ip) : _M_impl(__ip)
{ __ip->_M_add_reference(); } { __ip->_M_add_reference(); }

View File

@ -47,7 +47,7 @@ namespace std
// Clone existing _Impl object. // Clone existing _Impl object.
locale::_Impl:: locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs) _Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX : _M_references(__refs), _M_facets(0), _M_c_locale(0) // XXX
{ {
try try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); } { _M_facets = new __vec_facet(*(__imp._M_facets)); }
@ -69,7 +69,7 @@ namespace std
// Construct named _Impl, including the standard "C" locale. // Construct named _Impl, including the standard "C" locale.
locale::_Impl:: locale::_Impl::
_Impl(string __str, size_t __refs) _Impl(string __str, size_t __refs)
: _M_references(__refs - 1), _M_facets(0) : _M_references(__refs), _M_facets(0)
{ {
// Initialize the underlying locale model, which also checks to // Initialize the underlying locale model, which also checks to
// see if the given name is valid. // see if the given name is valid.
@ -184,8 +184,7 @@ namespace std
// Replacing an existing facet. // Replacing an existing facet.
// Order matters, here: // Order matters, here:
__fp->_M_add_reference(); __fp->_M_add_reference();
if (__fpr) __fpr->_M_remove_reference();
__fpr->_M_remove_reference();
__fpr = __fp; __fpr = __fp;
} }
else else
@ -198,4 +197,3 @@ namespace std
} }
} }
} // namespace std } // namespace std

View File

@ -86,46 +86,47 @@ test02()
VERIFY( loc_2 != loc_c ); VERIFY( loc_2 != loc_c );
// extract facet // extract facet
const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1); const numpunct<char>& nump_1 = use_facet<numpunct<char> >(loc_1);
const numpunct<char>& f_nump_2 = use_facet<numpunct<char> >(loc_2); const numpunct<char>& nump_2 = use_facet<numpunct<char> >(loc_2);
const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c); const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& f_nump_fr = use_facet<numpunct<char> >(loc_fr); const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr);
// sanity check the data is correct. // sanity check the data is correct.
char dp1 = f_nump_c.decimal_point(); char dp1 = nump_c.decimal_point();
char th1 = f_nump_c.thousands_sep(); char th1 = nump_c.thousands_sep();
string g1 = f_nump_c.grouping(); string g1 = nump_c.grouping();
string t1 = f_nump_c.truename(); string t1 = nump_c.truename();
string f1 = f_nump_c.falsename(); string f1 = nump_c.falsename();
char dp2 = f_nump_1.decimal_point(); char dp2 = nump_1.decimal_point();
char th2 = f_nump_1.thousands_sep(); char th2 = nump_1.thousands_sep();
string g2 = f_nump_1.grouping(); string g2 = nump_1.grouping();
string t2 = f_nump_1.truename(); string t2 = nump_1.truename();
string f2 = f_nump_1.falsename(); string f2 = nump_1.falsename();
char dp3 = f_nump_2.decimal_point(); char dp3 = nump_2.decimal_point();
char th3 = f_nump_2.thousands_sep(); char th3 = nump_2.thousands_sep();
string g3 = f_nump_2.grouping(); string g3 = nump_2.grouping();
string t3 = f_nump_2.truename(); string t3 = nump_2.truename();
string f3 = f_nump_2.falsename(); string f3 = nump_2.falsename();
char dp4 = f_nump_fr.decimal_point(); char dp4 = nump_fr.decimal_point();
char th4 = f_nump_fr.thousands_sep(); char th4 = nump_fr.thousands_sep();
string g4 = f_nump_fr.grouping(); string g4 = nump_fr.grouping();
string t4 = f_nump_fr.truename(); string t4 = nump_fr.truename();
string f4 = f_nump_fr.falsename(); string f4 = nump_fr.falsename();
#if 0
// XXX these should not be the same if named locales are working correctly.
VERIFY( dp1 != dp2 ); VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 ); VERIFY( th1 != th2 );
#endif
VERIFY( dp1 == dp3 ); VERIFY( dp1 == dp3 );
VERIFY( th1 == th3 ); VERIFY( th1 == th3 );
VERIFY( t1 == t3 ); VERIFY( t1 == t3 );
VERIFY( f1 == f3 ); VERIFY( f1 == f3 );
VERIFY( dp2 == dp4 );
VERIFY( th2 == th4 );
VERIFY( t2 == t4 );
VERIFY( f2 == f4 );
} }

View File

@ -22,13 +22,27 @@
#include <locale> #include <locale>
void test01()
{
// Check for required base class.
typedef std::numpunct<char> test_type;
typedef std::locale::facet base_type;
const test_type& obj = std::use_facet<test_type>(std::locale());
const base_type* base = &obj;
}
// Should be able to instantiate this for other types besides char, wchar_t // Should be able to instantiate this for other types besides char, wchar_t
class gnu_numpunct: public std::numpunct<unsigned char> class gnu_numpunct: public std::numpunct<unsigned char>
{ }; { };
void test02()
int main()
{ {
gnu_numpunct facet01; gnu_numpunct facet01;
}
int main()
{
test01();
test02();
return 0; return 0;
} }

View File

@ -42,19 +42,19 @@ void test01()
str = loc_fr.name(); str = loc_fr.name();
VERIFY( loc_c != loc_fr ); VERIFY( loc_c != loc_fr );
VERIFY( loc_us != loc_fr ); locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_c != loc_de );
locale loc_combo(loc_us, loc_fr, locale::numeric); VERIFY( loc_us != loc_fr );
str = loc_combo.name(); VERIFY( loc_us != loc_de );
VERIFY( loc_combo != loc_fr ); VERIFY( loc_de != loc_fr );
VERIFY( loc_combo != loc_us );
VERIFY( loc_combo != loc_c );
// cache the numpunct facets // cache the numpunct facets
const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c); const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& nump_us = use_facet<numpunct<char> >(loc_us); const numpunct<char>& nump_us = use_facet<numpunct<char> >(loc_us);
const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr); const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr);
const numpunct<char>& nump_combo = use_facet<numpunct<char> >(loc_combo); const numpunct<char>& nump_de = use_facet<numpunct<char> >(loc_de);
// sanity check the data is correct. // sanity check the data is correct.
char dp1 = nump_c.decimal_point(); char dp1 = nump_c.decimal_point();
@ -75,11 +75,27 @@ void test01()
string t3 = nump_fr.truename(); string t3 = nump_fr.truename();
string f3 = nump_fr.falsename(); string f3 = nump_fr.falsename();
char dp4 = nump_combo.decimal_point(); char dp4 = nump_de.decimal_point();
char th4 = nump_combo.thousands_sep(); char th4 = nump_de.thousands_sep();
string g4 = nump_combo.grouping(); string g4 = nump_de.grouping();
string t4 = nump_combo.truename(); string t4 = nump_de.truename();
string f4 = nump_combo.falsename(); string f4 = nump_de.falsename();
VERIFY( dp2 != dp3 );
VERIFY( th2 != th3 );
#if 0
// XXX isn't actually supported right now.
VERIFY( t2 != t3 );
VERIFY( f2 != f3 );
#endif
VERIFY( dp2 != dp4 );
VERIFY( th2 != th4 );
#if 0
// XXX isn't actually supported right now.
VERIFY( t2 != t3 );
VERIFY( f2 != f3 );
#endif
} }
int main() int main()