This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Revised locale caches


Hi, all.  Well, I think I've finally got a version of the locale
caches that satisfies the issues that were raised previously.  The
caches are now stored in the locale, so I don't run into the issue in
PR9828 that Petur raised.  Also, the default caches are static, so
there shouldn't be the allocation problems that Carlo was seeing.

(I hope :-)

One issue I think that could be up for discussion is whether we still
want a monolithic cache or a separate cache for each facet.

I believe this could be backported to 3.3 by playing ugly games with
tacking the caches onto the end of the locale::_Impl::_M_facets array.

Let the assault begin...

Jerry Quinn

2003-06-18  Jerry Quinn  <jlquinn@optonline.net>

	* config/linker-map.gnu: Add __locale_cache*.
	* include/bits/basic_ios.tcc (basic_ios::init,
	basic_ios::_M_cache_locale): Remove cache initialization.
	* include/bits/locale_classes.h
	(locale,locale::_Impl): Befriend use_cache.
	(__locale_cache_base): Declare.
	(locale::_Impl::_M_caches,locale::_Impl::_M_caches_size,
	locale::_Impl::_S_static_caches_size,
	locale::_Impl::_S_static_caches): New.
	(locale::_Impl::_M_get_cache): New function.
	(locale::_Impl::_M_install_cache): New function.
	* include/bits/locale_facets.h (__locale_cache): Declare.
	(numpunct): Befriend __locale_cache.
	(__locale_cache_base): Befriend locale, locale::_Impl.
	(__locale_cache_base::id): New class.
	(__locale_cache): Befriend locale, locale::_Impl.
	(__locale_cache::_M_id): New.
	(__locale_cache::_M_truename): Change to char array.
	(__locale_cache::_M_falsename): Change to char array.
	(__locale_cache::_M_grouping): Change to char array.
	(__locale_cache::__locale_cache(locale&)): New function.
	(__locale_cache::_M_init(locale&,bool)): New function.
	(__locale_cache::~__locale_cache): New function.
	* include/bits/locale_facets.tcc (use_cache): New function.
	(num_put::_M_convert_int,_M_convert_float,do_put): Use it.
	(__locale_cache::_M_init): Make raw char array copies of
	numpunct fields.
	(__locale_cache::_M_init(locale&,bool)): New.
	* src/globals.cc (locale_cache_c, locale_cache_w): New.
	* src/locale.cc (locale::_Impl::_S_static_caches): Define.
	* src/localename.cc (locale_cache_c, locale_cache_w): Declare.
	(locale::_Impl::~Impl): Destroy caches.
	(locale::_Impl::Impl):  Allocate and initialize cache storage.
	Fill in static caches.
	(__locale_cache::_M_id): Define.
	(__locale_cache_base::id::_S_highwater): Define.
	(__locale_cache_base::id::id): Define.


Index: config/linker-map.gnu
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v
retrieving revision 1.38
diff -c -r1.38 linker-map.gnu
*** config/linker-map.gnu	15 Jun 2003 23:24:00 -0000	1.38
--- config/linker-map.gnu	18 Jun 2003 05:45:25 -0000
***************
*** 55,61 ****
        std::__num_base::_S_format_float*;
        std::__num_base::_S_format_int*;
        std::__num_base::_S_atoms_in;
!       std::__num_base::_S_atoms_out
      };
  
      # Names not in an 'extern' block are mangled names.
--- 55,62 ----
        std::__num_base::_S_format_float*;
        std::__num_base::_S_format_int*;
        std::__num_base::_S_atoms_in;
!       std::__num_base::_S_atoms_out;
!       std::__locale_cache*;
      };
  
      # Names not in an 'extern' block are mangled names.
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.21
diff -c -r1.21 basic_ios.tcc
*** include/bits/basic_ios.tcc	13 May 2003 20:13:14 -0000	1.21
--- include/bits/basic_ios.tcc	18 Jun 2003 05:45:25 -0000
***************
*** 138,149 ****
        ios_base::_M_init();
  
        // Cache locale data and specific facets used by iostreams.
!       if (!_M_locale_cache.get())
! 	{
! 	  typedef __locale_cache<_CharT> __cache_t;
! 	  this->_M_locale_cache = auto_ptr<__locale_cache_base>(static_cast<__locale_cache_base*>(new __cache_t));
! 	  _M_cache_locale(_M_ios_locale);
! 	}
  
        // NB: The 27.4.4.1 Postconditions Table specifies requirements
        // after basic_ios::init() has been called. As part of this,
--- 138,144 ----
        ios_base::_M_init();
  
        // Cache locale data and specific facets used by iostreams.
!       _M_cache_locale(_M_ios_locale);
  
        // NB: The 27.4.4.1 Postconditions Table specifies requirements
        // after basic_ios::init() has been called. As part of this,
***************
*** 176,182 ****
  	_M_num_put = &use_facet<__numput_type>(__loc); 
        if (__builtin_expect(has_facet<__numget_type>(__loc), true))
  	_M_num_get = &use_facet<__numget_type>(__loc); 
-       static_cast<__locale_cache<_CharT>&>(_M_cache())._M_init(__loc); 
      }
  
    // Inhibit implicit instantiations for required instantiations,
--- 171,176 ----
Index: include/bits/locale_classes.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_classes.h,v
retrieving revision 1.6
diff -c -r1.6 locale_classes.h
*** include/bits/locale_classes.h	13 May 2003 20:13:14 -0000	1.6
--- include/bits/locale_classes.h	18 Jun 2003 05:45:25 -0000
***************
*** 72,77 ****
--- 72,81 ----
        friend const _Facet& 
        use_facet(const locale&);
       
+     template<typename _Cache>
+       friend const _Cache&
+       use_cache(const locale&);
+ 
      // Category values:
      // NB: Order must match _S_facet_categories definition in locale.cc
      static const category none		= 0;
***************
*** 176,181 ****
--- 180,186 ----
      _M_coalesce(const locale& __base, const locale& __add, category __cat);
    };
  
+   class __locale_cache_base;
  
    // Implementation object for locale 
    class locale::_Impl
***************
*** 193,198 ****
--- 198,207 ----
        friend bool  
        has_facet(const locale&) throw();
  
+     template<typename _Cache>
+       friend const _Cache&
+       use_cache(const locale&);
+ 
    private:
      // Data Members.
      _Atomic_word			_M_references;
***************
*** 207,212 ****
--- 216,230 ----
      static const locale::id* const 	_S_id_messages[];
      static const locale::id* const* const _S_facet_categories[];
  
+     // Storage for locale caches.
+     // If _M_caches != _S_static_caches, they're dynamic.
+     __locale_cache_base**		_M_caches;
+     size_t				_M_caches_size;
+ 
+     // For char and wchar_t
+     static const size_t			_S_static_caches_size = 2;
+     static __locale_cache_base*		_S_static_caches[];
+ 
      inline void 
      _M_add_reference() throw()
      { __atomic_add(&_M_references, 1); }
***************
*** 259,264 ****
--- 277,310 ----
        inline void 
        _M_init_facet(_Facet* __facet)
        { _M_install_facet(&_Facet::id, __facet);  }
+ 
+     // Retrieve the cache at __index.  0 is returned if the cache is
+     // missing.  Storage is expanded to be >= __index.
+     __locale_cache_base*
+       _M_get_cache(size_t __index)
+       {
+ 	if (__index >= _M_caches_size)
+ 	  {
+ 	    __locale_cache_base** __tmp =
+ 	      new __locale_cache_base*[__index + 4];
+ 	    for (size_t __i = 0; __i < _M_caches_size; ++__i)
+ 	      __tmp[__i] = _M_caches[__i];
+ 	    for (size_t __i = _M_caches_size; __i < __index + 4; ++__i)
+ 	      __tmp[__i] = 0;	
+ 	    // assert(_M_caches != _S_static_caches);
+ 	    delete [] _M_caches;
+ 	    _M_caches = __tmp;
+ 	    _M_caches_size = __index + 4;
+ 	  }
+ 	return _M_caches[__index];
+       }
+ 
+     // Save the supplied cache at __id.  Assumes _M_get_cache has been
+     // called.
+     void
+     _M_install_cache(__locale_cache_base* __cache, int __id)
+     {  _M_caches[__id] = __cache; }
+       
    };
  
    template<typename _Facet>
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.57
diff -c -r1.57 locale_facets.h
*** include/bits/locale_facets.h	7 May 2003 05:01:57 -0000	1.57
--- include/bits/locale_facets.h	18 Jun 2003 05:45:26 -0000
***************
*** 574,579 ****
--- 574,581 ----
      _S_format_float(const ios_base& __io, char* __fptr, char __mod);
    };
  
+   template<typename _CharT>
+   class __locale_cache;
  
    template<typename _CharT>
      class numpunct : public locale::facet
***************
*** 585,590 ****
--- 587,594 ----
  
        static locale::id 		id;
  
+       friend class __locale_cache<_CharT>;
+ 
      private:
        char_type 			_M_decimal_point;
        char_type 			_M_thousands_sep;
***************
*** 594,604 ****
  
      public:
        explicit 
!       numpunct(size_t __refs = 0) : locale::facet(__refs) 
        { _M_initialize_numpunct(); }
  
        explicit 
!       numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs) 
        { _M_initialize_numpunct(__cloc); }
  
        char_type    
--- 598,608 ----
  
      public:
        explicit 
!       numpunct(size_t __refs = 0) : locale::facet(__refs)
        { _M_initialize_numpunct(); }
  
        explicit 
!       numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
        { _M_initialize_numpunct(__cloc); }
  
        char_type    
***************
*** 1936,1946 ****
--- 1940,1986 ----
    // auto_ptr<__locale_cache_base> member of ios_base and directly
    // accessed via a casting to the derived __locale_cache<_CharT> in
    // parameterized facets.
+   //
    // The intent twofold: to avoid the costs of creating a locale
    // object and to avoid calling the virtual functions in a locale's
    // facet to look up data.
    class __locale_cache_base
    {
+     friend class std::locale::_Impl;
+     friend class locale;
+ 
+   public:
+     // Similar to locale::id.
+     class id
+     {
+       friend class locale::_Impl;
+ 
+       // NB: There is no accessor for _M_index because it may be used
+       // before the constructor is run; the effect of calling a member
+       // function (even an inline) would be undefined.
+       mutable size_t 		_M_index;
+ 
+       // Last id number assigned.
+       static _Atomic_word 	_S_highwater;   
+ 
+       void 
+       operator=(const id&);  // Not defined.
+ 
+       id(const id&);  // Not defined.
+ 
+     public:
+       // NB: This class is always a static data member, and thus can be
+       // counted on to be zero-initialized.
+       id();
+ 
+       inline size_t
+       _M_id() const
+       {
+ 	if (!_M_index)
+ 	  _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
+ 	return _M_index - 1;
+       }
+     };
    public:
      virtual
      ~__locale_cache_base() { }
***************
*** 1954,1959 ****
--- 1994,2010 ----
        typedef char_traits<_CharT>       traits_type;
        typedef basic_string<_CharT>	string_type;
  
+       friend class std::locale::_Impl;
+       friend class locale;
+ 
+       // XXX Using public because I can't for the life of me persuade
+       // g++ to give access to _M_id to locale::_Impl with friend
+       // decls.  gcc bug?
+     public:
+ 
+       // Give each specialization a unique id.
+       static id _M_id;
+ 
      public: 
        // Data Members:
  
***************
*** 1976,1983 ****
        
        // However the US's "false" and "true" are translated.  From
        // numpunct::truename() and numpunct::falsename(), respectively.
!       string_type 		_M_truename;
!       string_type 		_M_falsename;
  
        // If we are checking groupings. This should be equivalent to
        // numpunct::groupings().size() != 0
--- 2027,2034 ----
        
        // However the US's "false" and "true" are translated.  From
        // numpunct::truename() and numpunct::falsename(), respectively.
!       const _CharT*		_M_truename;
!       const _CharT*		_M_falsename;
  
        // If we are checking groupings. This should be equivalent to
        // numpunct::groupings().size() != 0
***************
*** 1985,1994 ****
  
        // If we are using numpunct's groupings, this is the current
        // grouping string in effect (from numpunct::grouping()).
!       string                    _M_grouping;
  
!       __locale_cache() : _M_use_grouping(false) 
!       { };
  
        __locale_cache& 
        operator=(const __locale_cache& __lc);
--- 2036,2051 ----
  
        // If we are using numpunct's groupings, this is the current
        // grouping string in effect (from numpunct::grouping()).
!       const char*               _M_grouping;
  
!       __locale_cache() : _M_truename(0), _M_falsename(0),
! 			 _M_use_grouping(false), _M_grouping(0)
!       { }
! 
!       __locale_cache(const locale& __loc)
! 	: _M_truename(0), _M_falsename(0), _M_use_grouping(false),
! 	  _M_grouping(0)
!       { _M_init(__loc); }
  
        __locale_cache& 
        operator=(const __locale_cache& __lc);
***************
*** 1996,2001 ****
--- 2053,2069 ----
        // Make sure the cache is built before the first use.
        void 
        _M_init(const locale&);
+ 
+       // For static initialization
+       void
+       _M_init(const locale&, bool);
+ 
+       ~__locale_cache()
+       {
+ 	delete [] _M_truename;
+ 	delete [] _M_falsename;
+ 	delete [] _M_grouping;
+       }
      };
  } // namespace std
  
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.99
diff -c -r1.99 locale_facets.tcc
*** include/bits/locale_facets.tcc	27 May 2003 21:14:49 -0000	1.99
--- include/bits/locale_facets.tcc	18 Jun 2003 05:45:26 -0000
***************
*** 86,91 ****
--- 86,106 ----
        return static_cast<const _Facet&>(*__facets[__i]);
      }
  
+   // Routine to access a cache for the locale.  If the cache didn't
+   // exist before, it gets constructed on the fly.
+   template<typename _Cache>
+     inline const _Cache&
+     use_cache(const locale& __loc)
+     {
+       size_t __i = _Cache::M_id._M_id();
+       __locale_cache_base* __cache = __loc._M_impl->_M_get_cache(__i);
+       if (!__cache)
+ 	{
+ 	  __cache = new _Cache(__loc);
+ 	  __loc._M_impl->_M_install_cache(__cache, __i);
+ 	}
+       return static_cast<const _Cache&>(*__cache);
+     }
  
    // Stage 1: Determine a conversion specifier.
    template<typename _CharT, typename _InIter>
***************
*** 769,778 ****
  		     _ValueT __v) const
        {
  	typedef __locale_cache<_CharT> __cache_type;
! 	__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
! 	_CharT* __lit = __lc._M_literals;
  
! 	// Long enough to hold hex, dec, and octal representations.
  	int __ilen = 4 * sizeof(_ValueT);
  	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  							     * __ilen));
--- 784,793 ----
  		     _ValueT __v) const
        {
  	typedef __locale_cache<_CharT> __cache_type;
! 	const __cache_type& __lc = use_cache<__cache_type>(__io.getloc());
! 	const _CharT* __lit = __lc._M_literals;
  
!  	// Long enough to hold hex, dec, and octal representations.
  	int __ilen = 4 * sizeof(_ValueT);
  	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  							     * __ilen));
***************
*** 873,880 ****
  	  __prec = static_cast<streamsize>(6);
  
  	typedef __locale_cache<_CharT> __cache_type;
! 	__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
! 
  	// [22.2.2.2.2] Stage 1, numeric conversion to character.
  	int __len;
  	// Long enough for the max format spec.
--- 888,894 ----
  	  __prec = static_cast<streamsize>(6);
  
  	typedef __locale_cache<_CharT> __cache_type;
! 	const __cache_type& __lc = use_cache<__cache_type>(__io.getloc());
  	// [22.2.2.2.2] Stage 1, numeric conversion to character.
  	int __len;
  	// Long enough for the max format spec.
***************
*** 975,981 ****
        else
          {
  	  typedef __locale_cache<_CharT> __cache_type;
! 	  __cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
  	  typedef basic_string<_CharT> 	__string_type;
  	  __string_type __name;
            if (__v)
--- 989,995 ----
        else
          {
  	  typedef __locale_cache<_CharT> __cache_type;
! 	  const __cache_type& __lc = use_cache<__cache_type>(__io.getloc());
  	  typedef basic_string<_CharT> 	__string_type;
  	  __string_type __name;
            if (__v)
***************
*** 2281,2293 ****
        if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
  	{
  	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- 	  _M_falsename = __np.falsename();
- 	  _M_truename = __np.truename();
  	  _M_thousands_sep = __np.thousands_sep();
  	  _M_decimal_point = __np.decimal_point();
! 	  _M_grouping = __np.grouping();
! 	  _M_use_grouping = _M_grouping.size() != 0 
! 	    		    && _M_grouping.data()[0] != 0;
  	}
        if (__builtin_expect(has_facet<ctype<_CharT> >(__loc), true))
  	{
--- 2295,2323 ----
        if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
  	{
  	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  	  _M_thousands_sep = __np.thousands_sep();
  	  _M_decimal_point = __np.decimal_point();
! 
! 	  string_type __false = __np.falsename();
! 	  _CharT* __falsename = new _CharT[__false.length() + 1];
! 	  __false.copy(__falsename, __false.length());
! 	  __falsename[__false.length()] = _CharT(); // XXX is this right?
! 	  _M_falsename = __falsename;
! 
! 	  string_type __true = __np.truename();
! 	  _CharT* __truename = new _CharT[__true.length() + 1];
! 	  __true.copy(__truename, __true.length());
! 	  __truename[__true.length()] = _CharT(); // XXX 
! 	  _M_truename = __truename;
! 
! 	  string __grouping = __np.grouping();
! 	  char* __group = new char[__grouping.length() + 1];
! 	  __grouping.copy(__group, __grouping.length());
! 	  __group[__grouping.length()] = 0;
! 	  _M_grouping = __group;
! 
! 	  _M_use_grouping = __grouping.length() != 0 
! 	    		    && __grouping.data()[0] != 0;
  	}
        if (__builtin_expect(has_facet<ctype<_CharT> >(__loc), true))
  	{
***************
*** 2296,2301 ****
--- 2326,2351 ----
  		     __num_base::_S_atoms_out + __num_base::_S_oend, 
  		     _M_literals);
  	}
+     }
+ 
+   // Static locale cache initialization.
+   template<typename _CharT>
+     void
+     __locale_cache<_CharT>::_M_init(const locale& __loc, bool)
+     {
+       // Grab pointers to numpunct static strings
+       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+       _M_thousands_sep = __np._M_thousands_sep;
+       _M_decimal_point = __np._M_decimal_point;
+       _M_falsename = __np._M_falsename;
+       _M_truename = __np._M_truename;
+       _M_grouping = __np._M_grouping;
+       _M_use_grouping = false;
+ 
+       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+       __ct.widen(__num_base::_S_atoms_out,
+ 		 __num_base::_S_atoms_out + __num_base::_S_oend, 
+ 		 _M_literals);
      }
  
    // Inhibit implicit instantiations for required instantiations,
Index: src/globals.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/globals.cc,v
retrieving revision 1.17
diff -c -r1.17 globals.cc
*** src/globals.cc	11 May 2003 04:20:56 -0000	1.17
--- src/globals.cc	18 Jun 2003 05:45:26 -0000
***************
*** 33,38 ****
--- 33,39 ----
  #include <locale>
  #include <ext/stdio_filebuf.h>
  #include <ext/stdio_sync_filebuf.h>
+ #include "bits/locale_facets.h"
  
  // On AIX, and perhaps other systems, library initialization order is
  // not guaranteed.  For example, the static initializers for the main
***************
*** 233,238 ****
--- 234,250 ----
    typedef char fake_messages_w[sizeof(messages<wchar_t>)]
    __attribute__ ((aligned(__alignof__(messages<wchar_t>))));
    fake_messages_w messages_w;
+ #endif
+ 
+   // Storage for static C locale caches
+   typedef char fake_locale_cache_c[sizeof(std::__locale_cache<char>)]
+   __attribute__ ((aligned(__alignof__(std::__locale_cache<char>))));
+   fake_locale_cache_c locale_cache_c;
+ 
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   typedef char fake_locale_cache_w[sizeof(std::__locale_cache<wchar_t>)]
+   __attribute__ ((aligned(__alignof__(std::__locale_cache<wchar_t>))));
+   fake_locale_cache_w locale_cache_w;
  #endif
  
    // Globals for once-only runtime initialization of mutex objects.  This
Index: src/locale.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/locale.cc,v
retrieving revision 1.82
diff -c -r1.82 locale.cc
*** src/locale.cc	7 May 2003 05:01:59 -0000	1.82
--- src/locale.cc	18 Jun 2003 05:45:27 -0000
***************
*** 531,535 ****
--- 531,538 ----
        *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
      *__fptr = '\0';
    }
+ 
+   __locale_cache_base* std::locale::_Impl::_S_static_caches[2];
+ 
  } // namespace std
  
Index: src/localename.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.39
diff -c -r1.39 localename.cc
*** src/localename.cc	28 Apr 2003 23:05:57 -0000	1.39
--- src/localename.cc	18 Jun 2003 05:45:27 -0000
***************
*** 69,74 ****
--- 69,79 ----
    extern time_put<wchar_t> 			time_put_w;
    extern std::messages<wchar_t> 		messages_w;
  #endif
+ 
+   extern std::__locale_cache<char>		locale_cache_c;
+ #ifdef  _GLIBCPP_USE_WCHAR_T
+   extern std::__locale_cache<wchar_t>		locale_cache_w;
+ #endif
  } // namespace __gnu_cxx
  
  namespace std
***************
*** 86,97 ****
      for (size_t __i = 0; __i < _S_categories_size; ++__i)
        delete [] _M_names[__i];  
      delete [] _M_names;
    }
  
    // Clone existing _Impl object.
    locale::_Impl::
    _Impl(const _Impl& __imp, size_t __refs)
!   : _M_references(__refs), _M_facets_size(__imp._M_facets_size) // XXX
    {
      try
        { 
--- 91,110 ----
      for (size_t __i = 0; __i < _S_categories_size; ++__i)
        delete [] _M_names[__i];  
      delete [] _M_names;
+ 
+     // Clean up caches.  No refcount for now.
+     if (_M_caches != _S_static_caches) {
+       for (size_t __i = 0; __i < _M_caches_size; ++__i)
+ 	delete _M_caches[__i];
+       delete [] _M_caches;
+     }
    }
  
    // Clone existing _Impl object.
    locale::_Impl::
    _Impl(const _Impl& __imp, size_t __refs)
!   : _M_references(__refs), _M_facets_size(__imp._M_facets_size),
!     _M_caches_size(__imp._M_caches_size)
    {
      try
        { 
***************
*** 126,137 ****
  	strcpy(__new, __imp._M_names[__i]);
  	_M_names[__i] = __new;
        }
    }
  
    // Construct named _Impl.
    locale::_Impl::
    _Impl(const char* __s, size_t __refs) 
!   : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS) 
    {
      // Initialize the underlying locale model, which also checks
      // to see if the given name is valid.
--- 139,165 ----
  	strcpy(__new, __imp._M_names[__i]);
  	_M_names[__i] = __new;
        }
+ 
+     // Allocate cache storage
+     try 
+       {
+       	_M_caches = new __locale_cache_base*[_M_caches_size];
+       }
+     catch(...)
+       {
+ 	delete [] _M_caches;
+ 	__throw_exception_again;
+       }
+ 
+     for (size_t __i = 0; __i < _M_caches_size; ++__i)
+       _M_caches[__i] = 0;
    }
  
    // Construct named _Impl.
    locale::_Impl::
    _Impl(const char* __s, size_t __refs) 
!     : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS),
!       _M_caches_size(_S_static_caches_size)
    {
      // Initialize the underlying locale model, which also checks
      // to see if the given name is valid.
***************
*** 218,229 ****
      _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
  #endif	  
      locale::facet::_S_destroy_c_locale(__cloc);
    }
  
    // Construct "C" _Impl.
    locale::_Impl::
    _Impl(facet**, size_t __refs, bool) 
!   : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
    {
      // Initialize the underlying locale model.
      locale::facet::_S_c_name[0] = 'C';
--- 246,272 ----
      _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
  #endif	  
      locale::facet::_S_destroy_c_locale(__cloc);
+ 
+     // Create cache storage
+     try 
+       {
+       	_M_caches = new __locale_cache_base*[_M_caches_size];
+       }
+     catch(...)
+       {
+ 	delete [] _M_caches;
+ 	__throw_exception_again;
+       }
+ 
+     for (size_t __i = 0; __i < _M_caches_size; ++__i)
+       _M_caches[__i] = 0;
    }
  
    // Construct "C" _Impl.
    locale::_Impl::
    _Impl(facet**, size_t __refs, bool) 
!     : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS),
!       _M_caches(_S_static_caches), _M_caches_size(_S_static_caches_size)
    {
      // Initialize the underlying locale model.
      locale::facet::_S_c_name[0] = 'C';
***************
*** 280,285 ****
--- 323,345 ----
      _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
      _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
  #endif 
+ 
+     // Initialize the static locale caches for C locale.
+ 
+     locale ltmp(this);		// Doesn't bump refcount
+     _M_add_reference();		// Bump so destructor doesn't trash us
+ 
+     // These need to be built in static allocated memory.  There must
+     // be a better way to do this!
+     __locale_cache<char>* __lc = new (&locale_cache_c) __locale_cache<char>();
+     _M_caches[__locale_cache<char>::_M_id._M_id()] = __lc;
+     __lc->_M_init(ltmp, true);
+       
+ #ifdef  _GLIBCPP_USE_WCHAR_T
+     __locale_cache<wchar_t>* __wlc = new (&locale_cache_w) __locale_cache<wchar_t>();
+     _M_caches[__locale_cache<wchar_t>::_M_id._M_id()] = __wlc;
+     __wlc->_M_init(ltmp, true);
+ #endif    
    }
    
    void
***************
*** 367,370 ****
--- 427,454 ----
  	  }
        }
    }
+ 
+   // Static decl for __locale_cache::id
+   template<typename _CharT>
+   __locale_cache_base::id __locale_cache<_CharT>::_M_id;
+ 
+   // Definitions for static const data members of locale::id
+   _Atomic_word __locale_cache_base::id::_S_highwater;  // init'd to 0 by linker
+ 
+   __locale_cache_base::id::id() 
+   { }
+ 
+   template class __locale_cache<char>;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+   template class __locale_cache<wchar_t>;
+ #endif
+ 
+     template
+     const __locale_cache<char>&
+     use_cache<__locale_cache<char> >(const locale& __loc);
+ 
+    template
+     const __locale_cache<wchar_t>&
+     use_cache<__locale_cache<wchar_t> >(const locale& __loc);
+ 
  } // namespace std


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