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]

second part of


This is another hunk of the PR 8761 and 707 fixups.

This adds ostreambuf_iterator specializatons for output speedups:
sputn fixups for facet output.

tested x86/linux

2003-02-05  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/locale_facets.tcc (time_put::do_put): Use __write.
	(money_put::do_put): Same.

2003-02-05  Jerry Quinn  <jlquinn@optonline.net>

	* include/bits/ios_base.h (ios_base): Document reserved storage.

	* include/bits/locale_facets.h:	(struct __pad): Comment on
	implementation.
	(__verify_grouping): Same.
	(__add_grouping): Same.		
	* include/bits/locale_facets.tcc (__verify_grouping): Move
	comments to declaration.
	(__add_grouping): Same.
	
	* include/bits/locale_facets.tcc: 
	(__write<_CharT, _OutIter>): New function.
	(__write<_CharT>): New function specialization.
	(num_put::_M_insert): Remove explicit loop over iterator.  Use
	__write.
	(num_put::_M_widen_float): Remove __basefield. 
	(num_put::_M_widen_int): Move __basefield to within grouping block.
	
	* include/bits/streambuf_iterator.h: Include <streambuf>.
	(ostreambuf_iterator::_M_put): Add.

Index: include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.22
diff -c -p -r1.22 ios_base.h
*** include/bits/ios_base.h	22 Jan 2003 16:51:51 -0000	1.22
--- include/bits/ios_base.h	6 Feb 2003 01:52:53 -0000
***************
*** 1,6 ****
  // Iostreams base classes -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // Iostreams base classes -*- C++ -*-
  
! // 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
*************** namespace std
*** 416,421 ****
--- 416,422 ----
      _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];  
  
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.52
diff -c -p -r1.52 locale_facets.h
*** include/bits/locale_facets.h	22 Jan 2003 16:51:51 -0000	1.52
--- include/bits/locale_facets.h	6 Feb 2003 01:52:54 -0000
*************** namespace std
*** 103,109 ****
      __convert_to_v(const char*, long double&, ios_base::iostate&, 
  		   const __c_locale&, int);
  
! 
    template<typename _CharT, typename _Traits>
      struct __pad
      {
--- 103,110 ----
      __convert_to_v(const char*, long double&, ios_base::iostate&, 
  		   const __c_locale&, int);
  
!   // NB: __pad is a struct, rather than a function, so it can be
!   // partially-specialized.
    template<typename _CharT, typename _Traits>
      struct __pad
      {
*************** namespace std
*** 113,128 ****
--- 114,165 ----
  	     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,  
  		   const char* __gbeg, const char* __gend, 
  		   const _CharT* __first, const _CharT* __last);
+ 
+   // This template permits specializing facet output code for
+   // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
+   // significantly more efficient than incrementing iterators.
+   template<typename _CharT>
+     inline
+     ostreambuf_iterator<_CharT>
+     __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
+     {
+       __s._M_put(__ws, __len);
+       return __s;
+     }
+ 
+   // This is the unspecialized form of the template.
+   template<typename _CharT, typename _OutIter>
+     inline
+     _OutIter
+     __write(_OutIter __s, const _CharT* __ws, int __len)
+     {
+       for (int __j = 0; __j < __len; __j++, ++__s)
+ 	*__s = __ws[__j];
+       return __s;
+     }
  
    // 22.2.1.1  Template class ctype
    // Include host and configuration specific ctype enums for ctype_base.
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.86
diff -c -p -r1.86 locale_facets.tcc
*** include/bits/locale_facets.tcc	1 Feb 2003 16:37:20 -0000	1.86
--- include/bits/locale_facets.tcc	6 Feb 2003 01:52:57 -0000
*************** namespace std
*** 750,756 ****
  //282. What types does numpunct grouping refer to?
        // Add grouping, if necessary. 
        const string __grouping = __np.grouping();
-       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
        if (__grouping.size())
  	{
  	  _CharT* __p2;
--- 750,755 ----
*************** namespace std
*** 797,803 ****
        // 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())
  	{
  	  // By itself __add_grouping cannot deal correctly with __ws when
--- 796,801 ----
*************** namespace std
*** 806,811 ****
--- 804,811 ----
  	  // However, remember that the latter do not occur if the number
  	  // printed is '0' (__len == 1).
  	  streamsize __off = 0;
+ 	  const ios_base::fmtflags __basefield = __io.flags() 
+ 	    					 & ios_base::basefield;
  	  if ((__io.flags() & ios_base::showbase) && __len > 1)
  	    if (__basefield == ios_base::oct)
  	      {
*************** namespace std
*** 840,845 ****
--- 840,846 ----
      {
        typedef char_traits<_CharT> 		__traits_type;
        // [22.2.2.2.2] Stage 3.
+       // If necessary, pad.
        streamsize __w = __io.width();
        _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  							    * __w));
*************** namespace std
*** 855,863 ****
  
        // [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;
      }
  
    template<typename _CharT, typename _OutIter>
--- 856,862 ----
  
        // [22.2.2.2.2] Stage 4.
        // Write resulting, fully-formatted string to output iterator.
!       return __write(__s, __ws, __len);
      }
  
    template<typename _CharT, typename _OutIter>
*************** namespace std
*** 1196,1202 ****
        char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
        int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
  #endif
!       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
        __ctype.widen(__cs, __cs + __len, __ws);
        string_type __digits(__ws);
        return this->do_put(__s, __intl, __io, __fill, __digits); 
--- 1195,1202 ----
        char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
        int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
  #endif
!       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
! 							   * __cs_size));
        __ctype.widen(__cs, __cs + __len, __ws);
        string_type __digits(__ws);
        return this->do_put(__s, __intl, __io, __fill, __digits); 
*************** namespace std
*** 1290,1296 ****
  		  const char* __gend = __gbeg + __grouping.size();
  		  const int __n = (__end - __beg) * 2;
  		  _CharT* __ws2 =
! 		    static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
  		  _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
  						    __gend, __beg, __end);
  		  __value.insert(0, __ws2, __ws_end - __ws2);
--- 1290,1296 ----
  		  const char* __gend = __gbeg + __grouping.size();
  		  const int __n = (__end - __beg) * 2;
  		  _CharT* __ws2 =
!        	          static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
  		  _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
  						    __gend, __beg, __end);
  		  __value.insert(0, __ws2, __ws_end - __ws2);
*************** namespace std
*** 1359,1366 ****
  	    }
  
  	  // Write resulting, fully-formatted string to output iterator.
! 	  for (size_type __j = 0; __j < __len; ++__j, ++__s)
! 	    *__s = __res[__j];
  	}
        __io.width(0);
        return __s; 
--- 1359,1365 ----
  	    }
  
  	  // Write resulting, fully-formatted string to output iterator.
! 	  __s = __write(__s, __res.c_str(), __len);
  	}
        __io.width(0);
        return __s; 
*************** namespace std
*** 1616,1622 ****
  		    ios_base::iostate& __err) const
      {
        typedef char_traits<_CharT> 		__traits_type;
!       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
        size_t __nmatches = 0;
        size_t __pos = 0;
        bool __testvalid = true;
--- 1615,1622 ----
  		    ios_base::iostate& __err) const
      {
        typedef char_traits<_CharT> 		__traits_type;
!       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 
! 							  * __indexlen));
        size_t __nmatches = 0;
        size_t __pos = 0;
        bool __testvalid = true;
*************** namespace std
*** 1633,1640 ****
  	  // Find smallest matching string.
  	  size_t __minlen = 10;
  	  for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
! 	    __minlen = std::min(__minlen, 
! 				__traits_type::length(__names[__matches[__i2]]));
  	  
  	  if (__pos < __minlen && __beg != __end)
  	    {
--- 1633,1640 ----
  	  // Find smallest matching string.
  	  size_t __minlen = 10;
  	  for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
! 	    __minlen = min(__minlen, 
! 			   __traits_type::length(__names[__matches[__i2]]));
  	  
  	  if (__pos < __minlen && __beg != __end)
  	    {
*************** namespace std
*** 1878,1885 ****
        // NB: This size is arbitrary. Should this be a data member,
        // initialized at construction?
        const size_t __maxlen = 64;
!       char_type* __res =
! 	static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
  
        // NB: In IEE 1003.1-200x, and perhaps other locale models, it
        // is possible that the format character will be longer than one
--- 1878,1884 ----
        // NB: This size is arbitrary. Should this be a data member,
        // initialized at construction?
        const size_t __maxlen = 64;
!       char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
  
        // NB: In IEE 1003.1-200x, and perhaps other locale models, it
        // is possible that the format character will be longer than one
*************** namespace std
*** 1903,1912 ****
        __tp._M_put(__res, __maxlen, __fmt, __tm);
  
        // Write resulting, fully-formatted string to output iterator.
!       size_t __len = char_traits<char_type>::length(__res);
!       for (size_t __i = 0; __i < __len; ++__i, ++__s)
! 	*__s = __res[__i];
!       return __s;
      }
  
  
--- 1902,1908 ----
        __tp._M_put(__res, __maxlen, __fmt, __tm);
  
        // Write resulting, fully-formatted string to output iterator.
!       return __write(__s, __res, char_traits<char_type>::length(__res));
      }
  
  
*************** namespace std
*** 1946,1953 ****
        // If the buffer was not large enough, try again with the correct size.
        if (__res >= __len)
  	{
! 	  __c =
! 	    static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
  	  _M_transform(__c, __lo, __res + 1);
  	}
        return string_type(__c);
--- 1942,1949 ----
        // If the buffer was not large enough, try again with the correct size.
        if (__res >= __len)
  	{
! 	  __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
! 						      * (__res + 1)));
  	  _M_transform(__c, __lo, __res + 1);
  	}
        return string_type(__c);
*************** namespace std
*** 1984,1990 ****
  				   const streamsize __oldlen, const bool __num)
      {
        size_t __plen = static_cast<size_t>(__newlen - __oldlen);
!       _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen));
        _Traits::assign(__pads, __plen, __fill); 
  
        _CharT* __beg;
--- 1980,1987 ----
  				   const streamsize __oldlen, const bool __num)
      {
        size_t __plen = static_cast<size_t>(__newlen - __oldlen);
!       _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
! 							     * __plen));
        _Traits::assign(__pads, __plen, __fill); 
  
        _CharT* __beg;
*************** namespace std
*** 2054,2067 ****
  			  __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, 
--- 2051,2056 ----
*************** namespace std
*** 2086,2096 ****
        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,  
--- 2075,2080 ----
Index: include/bits/streambuf_iterator.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/streambuf_iterator.h,v
retrieving revision 1.8
diff -c -p -r1.8 streambuf_iterator.h
*** include/bits/streambuf_iterator.h	31 Jul 2002 02:47:33 -0000	1.8
--- include/bits/streambuf_iterator.h	6 Feb 2003 01:52:57 -0000
***************
*** 1,6 ****
  // Streambuf iterators
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // Streambuf iterators
  
! // 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
***************
*** 28,35 ****
  // invalidate any other reasons why the executable file might be covered by
  // the GNU General Public License.
  
- // XXX Should specialize copy, find algorithms for streambuf iterators.
- 
  /** @file streambuf_iterator.h
   *  This is an internal header file, included by other library headers.
   *  You should not attempt to use it directly.
--- 28,33 ----
***************
*** 40,45 ****
--- 38,47 ----
  
  #pragma GCC system_header
  
+ #include <streambuf>
+ 
+ // NB: Should specialize copy, find algorithms for streambuf iterators.
+ 
  namespace std
  {
    // 24.5.3 Template class istreambuf_iterator
*************** namespace std
*** 166,172 ****
        bool 		_M_failed;
  
      public:
-       inline 
        ostreambuf_iterator(ostream_type& __s) throw ()
        : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
        
--- 168,173 ----
*************** namespace std
*** 174,180 ****
        : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
  
        ostreambuf_iterator& 
!       operator=(_CharT __c);
  
        ostreambuf_iterator& 
        operator*() throw()
--- 175,187 ----
        : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
  
        ostreambuf_iterator& 
!       operator=(_CharT __c)
!       {
! 	if (!_M_failed && 
! 	    _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
! 	  _M_failed = true;
! 	return *this;
!       }
  
        ostreambuf_iterator& 
        operator*() throw()
*************** namespace std
*** 191,206 ****
        bool 
        failed() const throw()
        { return _M_failed; }
-     };
  
!   template<typename _CharT, typename _Traits>
!     inline ostreambuf_iterator<_CharT, _Traits>&
!     ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
!     {
!       if (!_M_failed && 
!           _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
! 	_M_failed = true;
!       return *this;
!     }
  } // namespace std
  #endif
--- 198,210 ----
        bool 
        failed() const throw()
        { return _M_failed; }
  
!       ostreambuf_iterator& 
!       _M_put(const _CharT* __ws, streamsize __len)
!       {
! 	this->_M_sbuf->sputn(__ws, __len);
! 	return *this;
!       }
!     };
  } // namespace std
  #endif


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