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]

[patch] PR 8761 and 7076, mainline


I applied the integer IO output improvement patch to the mainline.  No
regressions, but there's an awful lot of tests that fail on missing locales.

The patch is the same as the one for the 3.3 branch except for two changes.
The first is the linker map, where I've included the format cache constructor
symbol in the 3.4 abi block.  The second, in __convert_from_int, outputs '0'
instead of '0x0' for showbase & hex.  This was turned up by a testcase on
mainline that isn't on the 3.3 branch.

This second change should also be put into the 3.3 branch patch along with a
test case.  Do you all want the 3.3 branch patch redone, or submit it as a
patch-with-testcase to the patch?

Jerry Quinn


2003-01-28 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: config/linker-map.gnu
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v
retrieving revision 1.29
diff -u -r1.29 linker-map.gnu
--- config/linker-map.gnu	24 Jan 2003 17:01:25 -0000	1.29
+++ config/linker-map.gnu	28 Jan 2003 14:31:14 -0000
@@ -141,6 +141,9 @@
 
     # std::__convert_to_v
     _ZSt14__convert_to_v*;
+ 
+    #std::_Format_cache<char>::_Format_cache[in-charge]()
+    _ZNSt13_Format_cacheIcEC1Ev;
 
     # stub functions from libmath
     sinf;
Index: include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.16
diff -u -r1.16 basic_ios.h
--- include/bits/basic_ios.h	22 Jan 2003 16:51:51 -0000	1.16
+++ include/bits/basic_ios.h	28 Jan 2003 14:31:41 -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
@@ -439,6 +439,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: 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
--- include/bits/basic_ios.tcc	1 Nov 2002 17:30:35 -0000	1.17
+++ include/bits/basic_ios.tcc	28 Jan 2003 14:31:41 -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: include/bits/ios_base.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.22
diff -u -r1.22 ios_base.h
--- include/bits/ios_base.h	22 Jan 2003 16:51:51 -0000	1.22
+++ include/bits/ios_base.h	28 Jan 2003 14:31:43 -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: include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.52
diff -u -r1.52 locale_facets.h
--- include/bits/locale_facets.h	22 Jan 2003 16:51:51 -0000	1.52
+++ include/bits/locale_facets.h	28 Jan 2003 14:31:44 -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: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.85
diff -u -r1.85 locale_facets.tcc
--- include/bits/locale_facets.tcc	22 Jan 2003 16:51:51 -0000	1.85
+++ include/bits/locale_facets.tcc	28 Jan 2003 14:31:45 -0000
@@ -686,39 +686,106 @@
 	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
+	  bool __showbase = ((__flags & ios_base::showbase) && __v); // Don't write base if already 0
+	  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 (__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 +851,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 +885,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 +896,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 +946,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 +2143,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 +2167,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 +2186,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: 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
--- include/bits/streambuf_iterator.h	31 Jul 2002 02:47:33 -0000	1.8
+++ include/bits/streambuf_iterator.h	28 Jan 2003 14:31:51 -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: src/ios.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.33
diff -u -r1.33 ios.cc
--- src/ios.cc	15 Nov 2002 19:12:31 -0000	1.33
+++ src/ios.cc	28 Jan 2003 14:32:04 -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: 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
--- src/locale-inst.cc	8 Oct 2002 23:32:23 -0000	1.35
+++ src/locale-inst.cc	28 Jan 2003 14:32:04 -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: src/localename.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.34
diff -u -r1.34 localename.cc
--- src/localename.cc	6 Jan 2003 21:22:59 -0000	1.34
+++ src/localename.cc	28 Jan 2003 14:32:05 -0000
@@ -1,4 +1,4 @@
-// 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
@@ -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]