This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] locale::_Impl tweaks
- To: gcc-patches at gcc dot gnu dot org
- Subject: [v3] locale::_Impl tweaks
- From: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Fri, 29 Jun 2001 21:35:10 -0700
Fixes ref counting in locale::_Impl.
Also, locale::combine was not cloning _Impl objects correctly, so use
of that member function was modifying the original locales, neg.
This will appear to give two new fails for a default-configured
library. These failures are not significant, and go away if configured
with --enable-clocale=gnu. For now, they'll fail with the default
configuration.
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.
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.16
diff -c -p -r1.16 locale_facets.tcc
*** locale_facets.tcc 2001/06/26 21:22:56 1.16
--- locale_facets.tcc 2001/06/30 04:27:27
***************
*** 42,57 ****
#include <typeinfo> // For bad_cast
#include <bits/std_vector.h>
-
namespace std
{
template<typename _Facet>
locale
locale::combine(const locale& __other)
{
! locale __copy(*this);
! __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id);
! return __copy;
}
template<typename _CharT, typename _Traits, typename _Alloc>
--- 42,56 ----
#include <typeinfo> // For bad_cast
#include <bits/std_vector.h>
namespace std
{
template<typename _Facet>
locale
locale::combine(const locale& __other)
{
! _Impl* __tmp = new _Impl(*_M_impl, 1);
! __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
! return locale(__tmp);
}
template<typename _CharT, typename _Traits, typename _Alloc>
Index: include/bits/localefwd.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/localefwd.h,v
retrieving revision 1.15
diff -c -p -r1.15 localefwd.h
*** localefwd.h 2001/03/14 20:46:34 1.15
--- localefwd.h 2001/06/30 04:27:28
*************** namespace std
*** 326,332 ****
inline void
_M_remove_reference() throw()
{
! if (_M_references-- == 0) // XXX MT
{
try
{ delete this; }
--- 326,332 ----
inline void
_M_remove_reference() throw()
{
! if (--_M_references == 0) // XXX MT
{
try
{ delete this; }
Index: src/locale.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale.cc,v
retrieving revision 1.33
diff -c -p -r1.33 locale.cc
*** locale.cc 2001/06/04 19:25:41 1.33
--- locale.cc 2001/06/30 04:27:31
*************** namespace std
*** 362,367 ****
--- 362,368 ----
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
+ // This is used to initialize global and classic locales.
locale::locale(_Impl* __ip) throw()
: _M_impl(__ip)
{ __ip->_M_add_reference(); }
Index: src/localename.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.14
diff -c -p -r1.14 localename.cc
*** localename.cc 2001/03/04 21:34:02 1.14
--- localename.cc 2001/06/30 04:27:32
*************** namespace std
*** 47,53 ****
// Clone existing _Impl object.
locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs)
! : _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX
{
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
--- 47,53 ----
// Clone existing _Impl object.
locale::_Impl::
_Impl(const _Impl& __imp, size_t __refs)
! : _M_references(__refs), _M_facets(0), _M_c_locale(0) // XXX
{
try
{ _M_facets = new __vec_facet(*(__imp._M_facets)); }
*************** namespace std
*** 69,75 ****
// Construct named _Impl, including the standard "C" locale.
locale::_Impl::
_Impl(string __str, size_t __refs)
! : _M_references(__refs - 1), _M_facets(0)
{
// Initialize the underlying locale model, which also checks to
// see if the given name is valid.
--- 69,75 ----
// Construct named _Impl, including the standard "C" locale.
locale::_Impl::
_Impl(string __str, size_t __refs)
! : _M_references(__refs), _M_facets(0)
{
// Initialize the underlying locale model, which also checks to
// see if the given name is valid.
*************** namespace std
*** 184,191 ****
// Replacing an existing facet.
// Order matters, here:
__fp->_M_add_reference();
! if (__fpr)
! __fpr->_M_remove_reference();
__fpr = __fp;
}
else
--- 184,190 ----
// Replacing an existing facet.
// Order matters, here:
__fp->_M_add_reference();
! __fpr->_M_remove_reference();
__fpr = __fp;
}
else
*************** namespace std
*** 198,201 ****
}
}
} // namespace std
-
--- 197,199 ----
Index: testsuite/22_locale/members.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/members.cc,v
retrieving revision 1.2
diff -c -p -r1.2 members.cc
*** members.cc 2001/05/12 16:51:41 1.2
--- members.cc 2001/06/30 04:27:33
*************** test02()
*** 86,131 ****
VERIFY( loc_2 != loc_c );
// extract facet
! const numpunct<char>& f_nump_1 = use_facet<numpunct<char> >(loc_1);
! const numpunct<char>& f_nump_2 = use_facet<numpunct<char> >(loc_2);
! const numpunct<char>& f_nump_c = use_facet<numpunct<char> >(loc_c);
! const numpunct<char>& f_nump_fr = use_facet<numpunct<char> >(loc_fr);
// sanity check the data is correct.
! char dp1 = f_nump_c.decimal_point();
! char th1 = f_nump_c.thousands_sep();
! string g1 = f_nump_c.grouping();
! string t1 = f_nump_c.truename();
! string f1 = f_nump_c.falsename();
!
! char dp2 = f_nump_1.decimal_point();
! char th2 = f_nump_1.thousands_sep();
! string g2 = f_nump_1.grouping();
! string t2 = f_nump_1.truename();
! string f2 = f_nump_1.falsename();
!
! char dp3 = f_nump_2.decimal_point();
! char th3 = f_nump_2.thousands_sep();
! string g3 = f_nump_2.grouping();
! string t3 = f_nump_2.truename();
! string f3 = f_nump_2.falsename();
!
! char dp4 = f_nump_fr.decimal_point();
! char th4 = f_nump_fr.thousands_sep();
! string g4 = f_nump_fr.grouping();
! string t4 = f_nump_fr.truename();
! string f4 = f_nump_fr.falsename();
!
! #if 0
! // XXX these should not be the same if named locales are working correctly.
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
- #endif
VERIFY( dp1 == dp3 );
VERIFY( th1 == th3 );
VERIFY( t1 == t3 );
VERIFY( f1 == f3 );
}
--- 86,132 ----
VERIFY( loc_2 != loc_c );
// extract facet
! const numpunct<char>& nump_1 = use_facet<numpunct<char> >(loc_1);
! const numpunct<char>& nump_2 = use_facet<numpunct<char> >(loc_2);
! const numpunct<char>& nump_c = use_facet<numpunct<char> >(loc_c);
! const numpunct<char>& nump_fr = use_facet<numpunct<char> >(loc_fr);
// sanity check the data is correct.
! char dp1 = nump_c.decimal_point();
! char th1 = nump_c.thousands_sep();
! string g1 = nump_c.grouping();
! string t1 = nump_c.truename();
! string f1 = nump_c.falsename();
!
! char dp2 = nump_1.decimal_point();
! char th2 = nump_1.thousands_sep();
! string g2 = nump_1.grouping();
! string t2 = nump_1.truename();
! string f2 = nump_1.falsename();
!
! char dp3 = nump_2.decimal_point();
! char th3 = nump_2.thousands_sep();
! string g3 = nump_2.grouping();
! string t3 = nump_2.truename();
! string f3 = nump_2.falsename();
!
! char dp4 = nump_fr.decimal_point();
! char th4 = nump_fr.thousands_sep();
! string g4 = nump_fr.grouping();
! string t4 = nump_fr.truename();
! string f4 = nump_fr.falsename();
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
VERIFY( dp1 == dp3 );
VERIFY( th1 == th3 );
VERIFY( t1 == t3 );
VERIFY( f1 == f3 );
+
+ VERIFY( dp2 == dp4 );
+ VERIFY( th2 == th4 );
+ VERIFY( t2 == t4 );
+ VERIFY( f2 == f4 );
}
Index: testsuite/22_locale/numpunct.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/numpunct.cc,v
retrieving revision 1.1
diff -c -p -r1.1 numpunct.cc
*** numpunct.cc 2001/01/30 09:18:51 1.1
--- numpunct.cc 2001/06/30 04:27:33
***************
*** 22,34 ****
#include <locale>
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_numpunct: public std::numpunct<unsigned char>
{ };
-
! int main()
{
gnu_numpunct facet01;
return 0;
}
--- 22,48 ----
#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
class gnu_numpunct: public std::numpunct<unsigned char>
{ };
! void test02()
{
gnu_numpunct facet01;
+ }
+
+ int main()
+ {
+ test01();
+ test02();
return 0;
}
Index: testsuite/22_locale/numpunct_char_members.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/numpunct_char_members.cc,v
retrieving revision 1.2
diff -c -p -r1.2 numpunct_char_members.cc
*** numpunct_char_members.cc 2001/05/12 16:51:41 1.2
--- numpunct_char_members.cc 2001/06/30 04:27:33
*************** void test01()
*** 42,60 ****
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
! VERIFY( loc_us != loc_fr );
! locale loc_combo(loc_us, loc_fr, locale::numeric);
! str = loc_combo.name();
! VERIFY( loc_combo != loc_fr );
! VERIFY( loc_combo != loc_us );
! VERIFY( loc_combo != loc_c );
// cache the numpunct facets
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_fr = use_facet<numpunct<char> >(loc_fr);
! const numpunct<char>& nump_combo = use_facet<numpunct<char> >(loc_combo);
// sanity check the data is correct.
char dp1 = nump_c.decimal_point();
--- 42,60 ----
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
! locale loc_de("de_DE");
! str = loc_de.name();
! VERIFY( loc_c != loc_de );
! VERIFY( loc_us != loc_fr );
! VERIFY( loc_us != loc_de );
! VERIFY( loc_de != loc_fr );
// cache the numpunct facets
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_fr = use_facet<numpunct<char> >(loc_fr);
! const numpunct<char>& nump_de = use_facet<numpunct<char> >(loc_de);
// sanity check the data is correct.
char dp1 = nump_c.decimal_point();
*************** void test01()
*** 75,85 ****
string t3 = nump_fr.truename();
string f3 = nump_fr.falsename();
! char dp4 = nump_combo.decimal_point();
! char th4 = nump_combo.thousands_sep();
! string g4 = nump_combo.grouping();
! string t4 = nump_combo.truename();
! string f4 = nump_combo.falsename();
}
int main()
--- 75,101 ----
string t3 = nump_fr.truename();
string f3 = nump_fr.falsename();
! char dp4 = nump_de.decimal_point();
! char th4 = nump_de.thousands_sep();
! string g4 = nump_de.grouping();
! string t4 = nump_de.truename();
! 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()