diff options
| author | Alexander Kabaev <kan@FreeBSD.org> | 2004-07-28 03:12:05 +0000 |
|---|---|---|
| committer | Alexander Kabaev <kan@FreeBSD.org> | 2004-07-28 03:12:05 +0000 |
| commit | ffeaf689a248da869b6bc8d4fd2233dfe513c060 (patch) | |
| tree | 75ef0e6da73746d6849e25a0996ae34e1aeff51d /contrib/libstdc++/include/bits/sstream.tcc | |
| parent | 9a63ad9273061dc19cbd117762e365ea9634e241 (diff) | |
Notes
Diffstat (limited to 'contrib/libstdc++/include/bits/sstream.tcc')
| -rw-r--r-- | contrib/libstdc++/include/bits/sstream.tcc | 220 |
1 files changed, 102 insertions, 118 deletions
diff --git a/contrib/libstdc++/include/bits/sstream.tcc b/contrib/libstdc++/include/bits/sstream.tcc index 606705c02e916..04cd6ec92a29d 100644 --- a/contrib/libstdc++/include/bits/sstream.tcc +++ b/contrib/libstdc++/include/bits/sstream.tcc @@ -1,6 +1,6 @@ // String based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2001, 2002 +// 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 @@ -32,8 +32,8 @@ // ISO C++ 14882: 27.7 String-based streams // -#ifndef _CPP_BITS_SSTREAM_TCC -#define _CPP_BITS_SSTREAM_TCC 1 +#ifndef _SSTREAM_TCC +#define _SSTREAM_TCC 1 #pragma GCC system_header @@ -42,75 +42,89 @@ namespace std { template <class _CharT, class _Traits, class _Alloc> - typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: pbackfail(int_type __c) { int_type __ret = traits_type::eof(); - bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); - bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; - - // Try to put back __c into input sequence in one of three ways. - // Order these tests done in is unspecified by the standard. - if (__testpos) + const bool __testeof = traits_type::eq_int_type(__c, __ret); + + if (this->eback() < this->gptr()) { - if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) - && !__testeof) - { - --_M_in_cur; - __ret = __c; - } - else if (!__testeof) - { - --_M_in_cur; - *_M_in_cur = traits_type::to_char_type(__c); - __ret = __c; - } + const bool __testeq = traits_type::eq(traits_type::to_char_type(__c), + this->gptr()[-1]); + this->gbump(-1); + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && __testeq) + __ret = __c; else if (__testeof) + __ret = traits_type::not_eof(__c); + else { - --_M_in_cur; - __ret = traits_type::not_eof(__c); + *this->gptr() = traits_type::to_char_type(__c); + __ret = __c; } } return __ret; } - + template <class _CharT, class _Traits, class _Alloc> - typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: overflow(int_type __c) { - int_type __ret = traits_type::eof(); - bool __testeof = traits_type::eq_int_type(__c, __ret); - bool __testwrite = _M_out_cur < _M_buf + _M_buf_size; - bool __testout = _M_mode & ios_base::out; + const bool __testout = this->_M_mode & ios_base::out; + if (__builtin_expect(!__testout, false)) + return traits_type::eof(); + + const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + if (__builtin_expect(__testeof, false)) + return traits_type::not_eof(__c); + + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); + const bool __testput = this->pptr() < this->epptr(); + if (__builtin_expect(!__testput && __capacity == __max_size, false)) + return traits_type::eof(); // Try to append __c into output sequence in one of two ways. // Order these tests done in is unspecified by the standard. - if (__testout) + if (!__testput) { - if (!__testeof) - { - __size_type __len = max(_M_buf_size, _M_buf_size_opt); - __len *= 2; + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // Then, in virtue of DR 169 (TC) we are allowed to grow more + // than one char. + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); + __string_type __tmp; + __tmp.reserve(__len); + __tmp.assign(_M_string.data(), this->epptr() - this->pbase()); + _M_string.swap(__tmp); + _M_sync(const_cast<char_type*>(_M_string.data()), + this->gptr() - this->eback(), this->pptr() - this->pbase()); + } + return this->sputc(traits_type::to_char_type(__c)); + } - if (__testwrite) - __ret = this->sputc(traits_type::to_char_type(__c)); - else if (__len <= _M_string.max_size()) - { - // Force-allocate, re-sync. - _M_string = this->str(); - _M_string.reserve(__len); - _M_buf_size = __len; - _M_really_sync(_M_in_cur - _M_in_beg, - _M_out_cur - _M_out_beg); - *_M_out_cur = traits_type::to_char_type(__c); - _M_out_cur_move(1); - __ret = __c; - } - } - else - __ret = traits_type::not_eof(__c); + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin) + { + // Update egptr() to match the actual string end. + _M_update_egptr(); + if (this->gptr() < this->egptr()) + __ret = traits_type::to_int_type(*this->gptr()); } return __ret; } @@ -120,55 +134,41 @@ namespace std basic_stringbuf<_CharT, _Traits, _Alloc>:: seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) { - pos_type __ret = pos_type(off_type(-1)); - bool __testin = (ios_base::in & _M_mode & __mode) != 0; - bool __testout = (ios_base::out & _M_mode & __mode) != 0; - bool __testboth = __testin && __testout && __way != ios_base::cur; + pos_type __ret = pos_type(off_type(-1)); + bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + const bool __testboth = __testin && __testout && __way != ios_base::cur; __testin &= !(__mode & ios_base::out); __testout &= !(__mode & ios_base::in); - if (_M_buf_size && (__testin || __testout || __testboth)) + if (_M_string.capacity() && (__testin || __testout || __testboth)) { - char_type* __beg = _M_buf; - char_type* __curi = NULL; - char_type* __curo = NULL; - char_type* __endi = NULL; - char_type* __endo = NULL; + char_type* __beg = __testin ? this->eback() : this->pbase(); - if (__testin || __testboth) - { - __curi = this->gptr(); - __endi = this->egptr(); - } - if (__testout || __testboth) - { - __curo = this->pptr(); - __endo = this->epptr(); - } + _M_update_egptr(); off_type __newoffi = 0; off_type __newoffo = 0; if (__way == ios_base::cur) { - __newoffi = __curi - __beg; - __newoffo = __curo - __beg; + __newoffi = this->gptr() - __beg; + __newoffo = this->pptr() - __beg; } else if (__way == ios_base::end) - { - __newoffi = __endi - __beg; - __newoffo = __endo - __beg; - } + __newoffo = __newoffi = this->egptr() - __beg; if ((__testin || __testboth) - && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off) + && __newoffi + __off >= 0 + && this->egptr() - __beg >= __newoffi + __off) { - _M_in_cur = __beg + __newoffi + __off; + this->gbump((__beg + __newoffi + __off) - this->gptr()); __ret = pos_type(__newoffi); } if ((__testout || __testboth) - && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off) + && __newoffo + __off >= 0 + && this->egptr() - __beg >= __newoffo + __off) { - _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg)); + this->pbump((__beg + __newoffo + __off) - this->pptr()); __ret = pos_type(__newoffo); } } @@ -180,42 +180,24 @@ namespace std basic_stringbuf<_CharT, _Traits, _Alloc>:: seekpos(pos_type __sp, ios_base::openmode __mode) { - pos_type __ret = pos_type(off_type(-1)); - - if (_M_buf_size) + pos_type __ret = pos_type(off_type(-1)); + if (_M_string.capacity()) { - off_type __pos = __sp; // Use streamoff operator to do conversion. - char_type* __beg = NULL; - char_type* __end = NULL; - bool __testin = (ios_base::in & _M_mode & __mode) != 0; - bool __testout = (ios_base::out & _M_mode & __mode) != 0; - bool __testboth = __testin && __testout; - __testin &= !(__mode & ios_base::out); - __testout &= !(__mode & ios_base::in); - - // NB: Ordered. - bool __testposi = false; - bool __testposo = false; - if (__testin || __testboth) - { - __beg = this->eback(); - __end = this->egptr(); - if (0 <= __pos && __pos <= __end - __beg) - __testposi = true; - } - if (__testout || __testboth) - { - __beg = this->pbase(); - __end = _M_buf + _M_buf_size; - if (0 <= __pos && __pos <= __end - __beg) - __testposo = true; - } - if (__testposi || __testposo) + off_type __pos (__sp); + const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + char_type* __beg = __testin ? this->eback() : this->pbase(); + + _M_update_egptr(); + + const bool __testpos = 0 <= __pos + && __pos <= this->egptr() - __beg; + if ((__testin || __testout) && __testpos) { - if (__testposi) - _M_in_cur = _M_in_beg + __pos; - if (__testposo) - _M_out_cur_move((__pos) - (_M_out_cur - __beg)); + if (__testin) + this->gbump((__beg + __pos) - this->gptr()); + if (__testout) + this->pbump((__beg + __pos) - this->pptr()); __ret = pos_type(off_type(__pos)); } } @@ -223,19 +205,21 @@ namespace std } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_stringbuf<char>; extern template class basic_istringstream<char>; extern template class basic_ostringstream<char>; extern template class basic_stringstream<char>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_stringbuf<wchar_t>; extern template class basic_istringstream<wchar_t>; extern template class basic_ostringstream<wchar_t>; extern template class basic_stringstream<wchar_t>; #endif +#endif } // namespace std #endif |
