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]

Re: [patch] PR 8761 and 7076, take 4


Fifth time's a charm :-)  No pest spray needed :-)

Updated to head of 3.3 branch.  No new regressions.  Fixed the comment for
__pad, used auto_ptr for the cache ptr, and added virtual functions to
ios_base.  Remove parts of patch that are no longer necessary.

Any more nits?

Later,
Jerry


2003-01-23 Jerry Quinn  <jlquinn@optonline.net>

	* config/linker-map.gnu (_Format_cache::_Format_cache()): Export.
	* include/bits/basic_ios.h (_Format_cache::_M_cache): Declare.
	* include/bits/basic_ios.tcc (basic_ios::copyfmt): Rebuild format cache.
	(basic_ios::imbue): Force format cache to be built.
	(basic_ios::_M_init): Create and initialize format cache.
	* include/bits/ios_base.h (_Format_cache_base): Declare.
	(ios_base): Document reserved storage.
	(ios_base::_M_format_cache): New.
	(ios_base::_M_cache): Define.
	(ios_base::_M_reserved1,ios_base::_M_reserved2): New.
	* include/bits/locale_facets.h:	(struct __pad): Comment on
	* implementation.
	(__verify_grouping): Same.
	(__add_grouping): Same.		
        (_Format_cache_base,_Format_cache<_CharT>):  New classes.
	(_Format_cache<char>, _Format_cache<wchar_t>): New specializations.
	* include/bits/locale_facets.tcc (__num_put_abs, __num_put_unsigned):
	New inline functions.
	(__convert_from_int): New.
	(num_put::_M_convert_int): Remove unused parameter names. Choose large
	enough buffer for text.  Use format cache literal string.  Use
	__convert_from_int.  Use __num_put_abs.  Use
	__num_put_unsigned. Formatted text is now at the end of the buffer.
	(num_put::_M_widen): Remove __loc.  Remove __ctype.  Remove __np.  Use
	_Format_cache.  Move __basefield to within grouping block.  Get
	grouping and thousands_sep info from cache.
	(__num_put_streambuf_write<_CharT, _OutIter>): New function.
	(__num_put_streambuf_write<_CharT>): New function specialization.
	(num_put::_M_insert): Remove explicit loop over iterator.  Use
	__num_put_streambuf_write.
	(_Format_cache<_CharT>::_Format_cache): New.
	(_Format_cache<_CharT>::_M_init): New.
	(_Format_cache<_CharT>::_M_populate): New.
	* include/bits/streambuf_iterator.h: Include <streambuf>.
	(ostreambuf_iterator): Add __num_put_streambuf_write as friend function.
	* src/ios.cc: Clear _M_format_cache in constructor.
	* src/locale-inst.cc (_Format_cache<char>, _Format_cache<_char_t>):
	New.
	(__convert_from_v<long long>, __convert_from_v<unsigned long long>):
	Add ifdef.
	(__convert_from_int<char,unsigned long>): New.
	(__convert_from_int<char,unsigned long long>): New.
	(__convert_from_int<wchar_t, unsigned long>): New.
	(__convert_from_int<wchar_t, unsigned long long>): New.
	* src/localenames.cc: Fix copyright years.
	(_Format_cache<char>::_Format_cache,
	_Format_cache<wchar_t>::_Format_cache): New.



Index: libstdc++-v3/config/linker-map.gnu
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v
retrieving revision 1.25.2.3
diff -u -r1.25.2.3 linker-map.gnu
--- libstdc++-v3/config/linker-map.gnu	23 Jan 2003 17:19:26 -0000	1.25.2.3
+++ libstdc++-v3/config/linker-map.gnu	25 Jan 2003 05:44:45 -0000
@@ -256,6 +256,12 @@
 
 } GLIBCPP_3.2.1;
 
+GLIBCPP_3.2.3 {
+
+  #std::_Format_cache<char>::_Format_cache[in-charge]()
+  _ZNSt13_Format_cacheIcEC1Ev;
+
+} GLIBCPP_3.2.2;
 
 # Symbols in the support library (libsupc++) have their own tag.
 CXXABI_1.2 {
Index: libstdc++-v3/include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.14.2.1
diff -u -r1.14.2.1 basic_ios.h
--- libstdc++-v3/include/bits/basic_ios.h	22 Jan 2003 17:39:50 -0000	1.14.2.1
+++ libstdc++-v3/include/bits/basic_ios.h	25 Jan 2003 05:44:45 -0000
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -432,6 +432,15 @@
 
       void
       _M_cache_facets(const locale& __loc);
+
+      _Format_cache<_CharT>&
+      _M_cache()
+      { return *(_Format_cache<_CharT>*)_M_format_cache.get(); }
+
+      const _Format_cache<_CharT>&
+      _M_cache() const
+      { return *(_Format_cache<_CharT>*)_M_format_cache.get(); }
+
     };
 } // namespace std
 
Index: libstdc++-v3/include/bits/basic_ios.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.17
diff -u -r1.17 basic_ios.tcc
--- libstdc++-v3/include/bits/basic_ios.tcc	1 Nov 2002 17:30:35 -0000	1.17
+++ libstdc++-v3/include/bits/basic_ios.tcc	25 Jan 2003 05:44:45 -0000
@@ -1,6 +1,6 @@
 // basic_ios locale and locale-related member functions -*- C++ -*-
 
-// Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -99,6 +99,9 @@
       this->exceptions(__rhs.exceptions());
       
       _M_call_callbacks(copyfmt_event);
+
+      _M_cache()._M_populate(*this);
+
       return *this;
     }
 
@@ -122,6 +125,9 @@
       return __ret;
     }
 
+  // Forward decl makes the _S_get call below happy.  Better way to do this?
+  template<typename _CharT> class _Format_cache;
+
   // Locales:
   template<typename _CharT, typename _Traits>
     locale
@@ -130,6 +136,8 @@
       locale __old(this->getloc());
       ios_base::imbue(__loc);
       _M_cache_facets(__loc);
+      // Force the cache to be rebuilt.
+      _M_cache()._M_populate(*this);
       if (this->rdbuf() != 0)
 	this->rdbuf()->pubimbue(__loc);
       return __old;
@@ -142,6 +150,12 @@
       // NB: This may be called more than once on the same object.
       ios_base::_M_init();
       _M_cache_facets(_M_ios_locale);
+      if (!_M_format_cache.get())
+	{
+	  this->_M_format_cache = auto_ptr<_Format_cache_base>(new _Format_cache<_CharT>);
+	  _Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&)_M_cache();
+	  __fc._M_init(*this);
+	}
       _M_tie = 0;
 
       // NB: The 27.4.4.1 Postconditions Table specifies requirements
Index: libstdc++-v3/include/bits/ios_base.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.21.2.2
diff -u -r1.21.2.2 ios_base.h
--- libstdc++-v3/include/bits/ios_base.h	23 Jan 2003 17:19:27 -0000	1.21.2.2
+++ libstdc++-v3/include/bits/ios_base.h	25 Jan 2003 05:44:46 -0000
@@ -146,6 +146,8 @@
 
   enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 };
 
+  class _Format_cache_base;
+
   // 27.4.2  Class ios_base
   /**
    *  @brief  The very top of the I/O class hierarchy.
@@ -416,6 +418,7 @@
     _Words  		_M_word_zero;    
 
     // Guaranteed storage.
+    // The first 5 iword and pword slots are reserved for internal use.
     static const int 	_S_local_word_size = 8;
     _Words  		_M_local_word[_S_local_word_size];  
 
@@ -429,6 +432,9 @@
     // Members for locale and locale caching.
     locale 		_M_ios_locale;
 
+    // Access to the format cache.  Cast this to _Format_cache<_CharT>*
+    auto_ptr<_Format_cache_base>	_M_format_cache;
+
     void 
     _M_init();
 
@@ -635,6 +641,14 @@
       return __word._M_pword;
     }
 
+    // Access to the cache.  Not safe to call until basic_ios::_M_init() has
+    // happened.
+    _Format_cache_base& _M_cache() { return *_M_format_cache; }
+
+    // Reserve space in virtual function table for now
+    virtual void _M_reserved1() {}
+    virtual void _M_reserved2() {}
+   
     // Destructor
     /**
      *  Destroys local storage and
Index: libstdc++-v3/include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.49.4.2
diff -u -r1.49.4.2 locale_facets.h
--- libstdc++-v3/include/bits/locale_facets.h	22 Jan 2003 17:39:50 -0000	1.49.4.2
+++ libstdc++-v3/include/bits/locale_facets.h	25 Jan 2003 05:44:46 -0000
@@ -103,7 +103,7 @@
     __convert_to_v(const char*, long double&, ios_base::iostate&, 
 		   const __c_locale&, int);
 
-
+  // NB: __pad is meant to be partially-specialized, for optimization.
   template<typename _CharT, typename _Traits>
     struct __pad
     {
@@ -113,11 +113,24 @@
 	     const streamsize __oldlen, const bool __num);
     };
 
+  // Used by both numeric and monetary facets.
+  // Check to make sure that the __grouping_tmp string constructed in
+  // money_get or num_get matches the canonical grouping for a given
+  // locale.
+  // __grouping_tmp is parsed L to R
+  // 1,222,444 == __grouping_tmp of "\1\3\3"
+  // __grouping is parsed R to L
+  // 1,222,444 == __grouping of "\3" == "\3\3\3"
   template<typename _CharT>
     bool
     __verify_grouping(const basic_string<_CharT>& __grouping, 
 		      basic_string<_CharT>& __grouping_tmp);
 
+  // Used by both numeric and monetary facets.
+  // Inserts "group separator" characters into an array of characters.
+  // It's recursive, one iteration per group.  It moves the characters
+  // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
+  // only with __gbeg != __gend.
   template<typename _CharT>
     _CharT*
     __add_grouping(_CharT* __s, _CharT __sep,  
@@ -1871,6 +1884,107 @@
     inline _CharT 
     tolower(_CharT __c, const locale& __loc)
     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+
+
+  // Pseudo pointer machinery for transparent casting from void* to
+  // _Format_cache<_CharT>
+  template<typename _CharT>
+    class _Format_cache;
+
+  class _Format_cache_base
+  {
+  public:
+    virtual
+    ~_Format_cache_base() {}
+  };
+
+  // _Format_cache holds the information extracted from the numpunct<> and
+  // moneypunct<> facets in a form optimized for parsing and formatting.  It
+  // is stored as a member of basic_ios and accessed via a void* pointer in
+  // the ios_base object passed to the _get and _put facets.
+
+  // Its intent is to avoid the cost of creating a locale object and
+  // calling the virtual functions in locale facets.
+  template<typename _CharT>
+  class _Format_cache : public _Format_cache_base
+    {
+      // Types:
+      typedef _CharT               	char_type;
+      typedef char_traits<_CharT>       traits_type;
+      typedef basic_string<_CharT>	string_type;
+
+
+    public: 
+      // Data Members:
+
+      // A list of valid numeric literals: for the standard "C" locale, this
+      // is "-+xX0123456789abcdef0123456789ABCDEF".  This array contains the
+      // chars after having been passed through the current locale's
+      // ctype<_CharT>.widen().
+      // 
+
+      // NB: code depends on the order of definitions of the names
+      // these are indices into _M_numeric_literals, below.
+      // This string is formatted for putting, not getting. (output, not input)
+      enum 
+      {  
+        _S_minus, 
+        _S_plus, 
+        _S_x, 
+        _S_X, 
+        _S_digits,
+        _S_digits_end = _S_digits + 16,
+        _S_udigits = _S_digits_end,  
+        _S_udigits_end = _S_udigits + 16,
+        _S_ee = _S_digits + 14, // For scientific notation, 'e'
+        _S_Ee = _S_udigits + 14 // For scientific notation, 'E'
+      };
+
+      _CharT                    _M_literals[_S_udigits_end];
+
+     
+      // The sign used to separate decimal values: for standard US
+      // locales, this would usually be: "."
+      // Abstracted from numpunct::decimal_point().
+      _CharT                    _M_decimal_point;
+
+      // The sign used to separate groups of digits into smaller
+      // strings that the eye can parse with less difficulty: for
+      // standard US locales, this would usually be: ","
+      // Abstracted from numpunct::thousands_sep().
+      _CharT                    _M_thousands_sep;
+      
+      // 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
+      bool                      _M_use_grouping;
+
+      // If we are using numpunct's groupings, this is the current grouping
+      // string in effect (from numpunct::grouping()).
+      string                    _M_grouping;
+
+      _Format_cache();
+
+      _Format_cache& operator=(const _Format_cache& __fc);
+
+
+      // Make sure the cache is built before the first use.
+      void _M_init(ios_base&);
+
+      void 
+      _M_populate (ios_base&);
+    };
+
+  template<>
+    _Format_cache<char>::_Format_cache();
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template<>
+    _Format_cache<wchar_t>::_Format_cache();
+#endif
 } // namespace std
 
 #endif
Index: libstdc++-v3/include/bits/locale_facets.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.82.4.2
diff -u -r1.82.4.2 locale_facets.tcc
--- libstdc++-v3/include/bits/locale_facets.tcc	22 Jan 2003 17:39:50 -0000	1.82.4.2
+++ libstdc++-v3/include/bits/locale_facets.tcc	25 Jan 2003 05:44:47 -0000
@@ -686,39 +686,105 @@
 	return _M_widen_float(__s, __io, __fill, __cs, __len);
       }
 
+  // num_put::_M_convert_int is only ever specialized with long, unsigned
+  // long, long long, and unsigned long long.  These adapters permit calling
+  // into unsigned long and unsigned long long functions.
+  inline unsigned long __num_put_abs(long __v) { return -(unsigned long)__v; }
+  inline unsigned long __num_put_abs(unsigned long __v) { return __v; }
+  inline unsigned long __num_put_unsigned(long __v) { return (unsigned long)__v; }
+  inline unsigned long __num_put_unsigned(unsigned long __v) { return __v; }
+#ifdef _GLIBCPP_USE_LONG_LONG
+  inline unsigned long long __num_put_abs(long long __v) { return -(unsigned long long)__v; }
+  inline unsigned long long __num_put_abs(unsigned long long __v) { return __v; }
+  inline unsigned long long __num_put_unsigned(long long __v) { return -(unsigned long long)__v; }
+  inline unsigned long long __num_put_unsigned(unsigned long long __v) { return __v; }
+#endif
+
+  // Only called with unsigned long and unsigned long long
+  template<typename _CharT, typename _ValueT>
+    int
+    __convert_from_int(_CharT* __out, const int __size, _ValueT __v,
+		       const _CharT* __lit, ios_base::fmtflags __flags, 
+		       bool __neg)
+    {
+      _CharT* __bufptr = __out + __size - 1;
+      _CharT* __bufend = __out + __size;
+      ios_base::fmtflags __bf = __flags & ios_base::basefield;
+
+      if (__builtin_expect(__bf == ios_base::oct, false))
+	{
+	  // Octal
+	  bool __showbase = ((__flags & ios_base::showbase) && __v); // Don't write base if already 0
+	  do {
+	    *__bufptr-- = __lit[(__v & 0x7) + _Format_cache<_CharT>::_S_digits];
+	    __v >>=3;
+	  } while (__v != 0);
+	  if (__showbase)
+	    *__bufptr-- = __lit[_Format_cache<_CharT>::_S_digits];
+	}
+      else if (__builtin_expect(__bf == ios_base::hex, false))
+	{
+	  // Hex
+	  int __case_offset = (__flags & ios_base::uppercase)
+	    ? _Format_cache<_CharT>::_S_udigits
+	    : _Format_cache<_CharT>::_S_digits;
+	  do {
+	    *__bufptr-- = __lit[(__v & 0xf) + __case_offset];
+	    __v >>=4;
+	  } while (__v != 0);
+	  if (__flags & ios_base::showbase)
+	    {
+	      // 'x' or 'X'
+	      *__bufptr-- = __lit[_Format_cache<_CharT>::_S_x +
+				  (int)(!!(__flags & ios_base::uppercase))];
+	      // '0'
+	      *__bufptr-- = __lit[_Format_cache<_CharT>::_S_digits];
+	    }
+	}
+      else
+	{
+	  // Decimal
+	  do {
+	    *__bufptr-- = __lit[(__v % 10) + _Format_cache<_CharT>::_S_digits];
+	    __v /= 10;
+	  } while (__v != 0);
+	  if (__neg)
+	    *__bufptr-- = __lit[_Format_cache<_CharT>::_S_minus];
+	  else if (__flags & ios_base::showpos)
+	    *__bufptr-- = __lit[_Format_cache<_CharT>::_S_plus];
+	}
+      int __ret = __bufend - __bufptr - 1;
+      return __ret;
+    }
+
   template<typename _CharT, typename _OutIter>
     template<typename _ValueT>
       _OutIter
       num_put<_CharT, _OutIter>::
-      _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
-		     char __modl, _ValueT __v) const
+      _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char,
+		     char, _ValueT __v) const
       {
 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
 
-	// Long enough for the max format spec.
-	char __fbuf[16];
-	_S_format_int(__io, __fbuf, __mod, __modl);
-#ifdef _GLIBCPP_USE_C99
-	// First try a buffer perhaps big enough.
-	int __cs_size = 64;
-	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-	int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
-				     _S_c_locale);
-	// If the buffer was not large enough, try again with the correct size.
-	if (__len >= __cs_size)
-	  {
-	    __cs_size = __len + 1;
-	    __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-	    __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
-				     _S_c_locale);
-	  }
-#else
-	// Leave room for "+/-," "0x," and commas. This size is
-	// arbitrary, but should be largely sufficient.
-	char __cs[128];
-	int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
-#endif
-	return _M_widen_int(__s, __io, __fill, __cs, __len);
+	// Long enough to hold hex, dec, and octal representations.
+	int __cs_size = 4 * sizeof(_ValueT);
+	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
+							     * __cs_size));
+	_Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&) __io._M_cache();
+	_CharT* __lit = __fc._M_literals;
+
+	int __len;
+	// Choose the adaptor required to convert the value for calling into
+	// an unsigned long (long) rendering function.  Result is returned
+	// right-justified in the buffer.
+	if (__v < 0)
+	  __len = __convert_from_int(&__cs[0], __cs_size, __num_put_abs(__v),
+				     __lit, __io.flags(), true);
+	else
+	  __len = __convert_from_int(&__cs[0], __cs_size, __num_put_unsigned(__v),
+				     __lit, __io.flags(), false);
+
+	return _M_widen_int(__s, __io, __fill, (char*)(__cs + __cs_size - __len), __len);
       }
 
   template<typename _CharT, typename _OutIter>
@@ -784,22 +850,21 @@
     {
       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
       // numpunct.decimal_point() values for '.' and adding grouping.
-      const locale __loc = __io.getloc();
-      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
-      _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-							   * __len));
+
+      _CharT* __ws = (_CharT*)__cs;
       // Grouping can add (almost) as many separators as the number of
       // digits, but no more.
       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
 							    * __len * 2));
-      __ctype.widen(__cs, __cs + __len, __ws);
+
+      _Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&)__io._M_cache();
+
 
       // Add grouping, if necessary. 
-      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
-      const string __grouping = __np.grouping();
-      const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
-      if (__grouping.size())
+      if (__fc._M_use_grouping)
 	{
+	  const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+
 	  // By itself __add_grouping cannot deal correctly with __ws when
 	  // ios::showbase is set and ios_base::oct || ios_base::hex.
 	  // Therefore we take care "by hand" of the initial 0, 0x or 0X.
@@ -819,9 +884,9 @@
 		*(__ws2 + 1) = *(__ws + 1);
 	      }
 	  _CharT* __p;
-	  __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), 
-			       __grouping.c_str(),
-			       __grouping.c_str() + __grouping.size(),
+	  __p = __add_grouping(__ws2 + __off, __fc._M_thousands_sep, 
+			       __fc._M_grouping.c_str(),
+			       __fc._M_grouping.c_str() + __fc._M_grouping.size(),
 			       __ws + __off, __ws + __len);
 	  __len = __p - __ws2;
 	  // Switch strings.
@@ -830,6 +895,31 @@
       return _M_insert(__s, __io, __fill, __ws, __len);
     }
 
+  
+  // This template permits specializing the stage 4 output code in _M_insert
+  // on ostreambuf_iterator.  For the streambufs, sputn is significantly more
+  // efficient than incrementing iterators.
+  template<typename _CharT>
+    inline
+    ostreambuf_iterator<_CharT>
+    __num_put_streambuf_write (ostreambuf_iterator<_CharT> __s, const _CharT* __ws,
+		      int __len)
+    {
+      __s._M_sbuf->sputn(__ws, __len);
+      return __s;
+    }
+
+  // This is the unspecialized form of the template
+  template<typename _CharT, typename _OutIter>
+    inline
+    _OutIter
+    __num_put_streambuf_write(_OutIter __s, const _CharT* __ws, int __len)
+    {
+      for (int __j = 0; __j < __len; __j++, ++__s)
+	*__s = __ws[__j];
+      return __s;
+    }
+
   // For use by integer and floating-point types after they have been
   // converted into a char_type string.
   template<typename _CharT, typename _OutIter>
@@ -855,9 +945,7 @@
 
       // [22.2.2.2.2] Stage 4.
       // Write resulting, fully-formatted string to output iterator.
-      for (int __j = 0; __j < __len; ++__j, ++__s)
-	*__s = __ws[__j];
-      return __s;
+      return __num_put_streambuf_write(__s, __ws, __len);
     }
 
   template<typename _CharT, typename _OutIter>
@@ -2054,14 +2142,6 @@
 			  __newlen - __beglen - __mod);
     }
 
-  // Used by both numeric and monetary facets.
-  // Check to make sure that the __grouping_tmp string constructed in
-  // money_get or num_get matches the canonical grouping for a given
-  // locale.
-  // __grouping_tmp is parsed L to R
-  // 1,222,444 == __grouping_tmp of "/1/3/3"
-  // __grouping is parsed R to L
-  // 1,222,444 == __grouping of "/3" == "/3/3/3"
   template<typename _CharT>
     bool
     __verify_grouping(const basic_string<_CharT>& __grouping, 
@@ -2086,11 +2166,6 @@
       return __test;
     }
 
-  // Used by both numeric and monetary facets.
-  // Inserts "group separator" characters into an array of characters.
-  // It's recursive, one iteration per group.  It moves the characters
-  // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
-  // only with __gbeg != __gend.
   template<typename _CharT>
     _CharT*
     __add_grouping(_CharT* __s, _CharT __sep,  
@@ -2110,6 +2185,62 @@
       while (__first != __last);
       return __s;
     }
+
+  template<typename _CharT>
+    inline
+    _Format_cache<_CharT>::_Format_cache()
+    : _M_use_grouping(false)
+    { }
+
+  // Cache initialization
+  template<typename _CharT>
+    inline
+    void
+    _Format_cache<_CharT>::_M_init(ios_base& __io)
+    { _M_populate(__io); }
+
+  // char and wchar_t specializations start out valid, so no need to call
+  // _M_populate
+  template<>
+    inline
+    void
+    _Format_cache<char>::_M_init(ios_base&)
+    { }
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template<>
+    inline
+    void
+    _Format_cache<wchar_t>::_M_init(ios_base&)
+    { }
+#endif
+
+
+  template<typename _CharT>
+    void
+    _Format_cache<_CharT>::_M_populate(ios_base& __io)
+    {
+      static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+      locale __loc = __io.getloc();
+      if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
+	{
+	  numpunct<_CharT> const& __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))
+	{
+	  ctype<_CharT> const& __ct = use_facet< ctype<_CharT> >(__loc);
+	  __ct.widen(_S_numeric_literals, 
+		     _S_numeric_literals + _S_literal_count, _M_literals);
+	}
+    }
+
 
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.  
Index: libstdc++-v3/include/bits/streambuf_iterator.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/streambuf_iterator.h,v
retrieving revision 1.8
diff -u -r1.8 streambuf_iterator.h
--- libstdc++-v3/include/bits/streambuf_iterator.h	31 Jul 2002 02:47:33 -0000	1.8
+++ libstdc++-v3/include/bits/streambuf_iterator.h	25 Jan 2003 05:44:47 -0000
@@ -1,6 +1,6 @@
 // Streambuf iterators
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -40,6 +40,8 @@
 
 #pragma GCC system_header
 
+#include <streambuf>
+
 namespace std
 {
   // 24.5.3 Template class istreambuf_iterator
@@ -191,6 +193,10 @@
       bool 
       failed() const throw()
       { return _M_failed; }
+
+      friend ostreambuf_iterator<_CharT>
+	__num_put_streambuf_write<_CharT>(ostreambuf_iterator<_CharT> __s,
+					  const _CharT* __ws, int __len);
     };
 
   template<typename _CharT, typename _Traits>
Index: libstdc++-v3/src/ios.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.33
diff -u -r1.33 ios.cc
--- libstdc++-v3/src/ios.cc	15 Nov 2002 19:12:31 -0000	1.33
+++ libstdc++-v3/src/ios.cc	25 Jan 2003 05:44:47 -0000
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -301,7 +301,7 @@
     return __old;
   }
 
-  ios_base::ios_base() : _M_callbacks(0), _M_word(0)
+  ios_base::ios_base() : _M_callbacks(0), _M_word(0), _M_format_cache(0)
   {
     // Do nothing: basic_ios::init() does it.  
     // NB: _M_callbacks and _M_word must be zero for non-initialized
Index: libstdc++-v3/src/locale-inst.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.35
diff -u -r1.35 locale-inst.cc
--- libstdc++-v3/src/locale-inst.cc	8 Oct 2002 23:32:23 -0000	1.35
+++ libstdc++-v3/src/locale-inst.cc	25 Jan 2003 05:44:47 -0000
@@ -1,6 +1,6 @@
 // Locale support -*- C++ -*-
 
-// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -46,6 +46,7 @@
   template class moneypunct_byname<char, true>;
   template class money_get<char, istreambuf_iterator<char> >;
   template class money_put<char, ostreambuf_iterator<char> >;
+  template class _Format_cache<char>;
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template class moneypunct<wchar_t, false>;
@@ -54,6 +55,7 @@
   template class moneypunct_byname<wchar_t, true>;
   template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
   template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+  template class _Format_cache<wchar_t>;
 #endif
 
   // numpunct, numpunct_byname, num_get, and num_put
@@ -451,6 +453,7 @@
     __convert_from_v(char*, const int, const char*, unsigned long, 
 		     const __c_locale&, int);
 
+#ifdef _GLIBCPP_USE_LONG_LONG
   template
     int
     __convert_from_v(char*, const int, const char*, long long, 
@@ -460,4 +463,35 @@
     int
     __convert_from_v(char*, const int, const char*, unsigned long long, 
 		     const __c_locale&, int);
+#endif
+
+  template
+    int
+    __convert_from_int(char* __out, const int __size, unsigned long __v,
+		       const char* __lit, ios_base::fmtflags __flags, 
+		       bool __neg);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template
+    int
+    __convert_from_int(wchar_t* __out, const int __size, unsigned long __v,
+		       const wchar_t* __lit, ios_base::fmtflags __flags, 
+		       bool __neg);
+#endif
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  template
+    int
+    __convert_from_int(char* __out, const int __size, unsigned long long __v,
+		       const char* __lit, ios_base::fmtflags __flags, 
+		       bool __neg);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template
+    int
+    __convert_from_int(wchar_t* __out, const int __size, unsigned long long __v,
+		       const wchar_t* __lit, ios_base::fmtflags __flags, 
+		       bool __neg);
+#endif
+#endif
 } // namespace std
Index: libstdc++-v3/src/localename.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.33.2.2
diff -u -r1.33.2.2 localename.cc
--- libstdc++-v3/src/localename.cc	23 Jan 2003 17:19:28 -0000	1.33.2.2
+++ libstdc++-v3/src/localename.cc	25 Jan 2003 05:44:47 -0000
@@ -1,4 +1,4 @@
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002m 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -350,4 +350,28 @@
 	  }
       }
   }
+
+  template<>
+    _Format_cache<char>::_Format_cache()
+    : _M_decimal_point('.'), _M_thousands_sep(','),
+      _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
+    {
+      static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+      copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+    }
+ 
+#ifdef  _GLIBCPP_USE_WCHAR_T
+  template<>
+    _Format_cache<wchar_t>::_Format_cache()
+    : _M_decimal_point(L'.'), _M_thousands_sep(L','),
+      _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
+    {
+      static const wchar_t _S_numeric_literals[] = L"-+xX0123456789abcdef0123456789ABCDEF";
+      static const int _S_literal_count = (sizeof(_S_numeric_literals) - 1) / sizeof(wchar_t);
+
+      copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+    }
+#endif
 } // namespace std


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