This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[v3] locale::_Impl tweaks



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()


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]