This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
second part of
- From: Benjamin Kosnik <bkoz at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org, jlquinn at optonline dot net
- Date: Wed, 5 Feb 2003 21:56:12 -0600
- Subject: 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