Nathan C.
2003-06-22 Paolo Carlini <pcarlini@unitus.it> Nathan C. Myers <ncm-nospam@cantrip.org> * include/std/std_streambuf.h (_M_move_out_cur): _M_out_lim is now used only for filebuf, when _M_buf_unified is true. epgtr() plays the role of _M_out_lim but it's only updated upon overflow, underflow, uflow, seekoff/pos. * include/bits/sstream.tcc (_M_underflow): New, implements stringbuf::underflow and uflow. (seekoff, seekpos): Tweak, use _M_update_egptr. * include/std/std_sstream.h (str): Rewrote, deal correctly with the new logic, in particular, when pptr() > egptr(). (_M_sync): When __testout && !__testin set all the get area pointers to the current string end. (_M_update_egptr): New, internal function updating egptr() to the actual string end. (_M_underflow): New, declare. (underflow): Dispatch to _M_underflow(false). (uflow): Dispatch to _M_underflow(true). * include/bits/sstream.tcc (pbackfail, overflow, seekoff, seekpos): Use only the documented derivation interface to basic_streambuf (gptr(), setg(), etc.) to work right with user specializations. * include/std/std_sstream.h (str, _M_sync): Likewise. From-SVN: r68347
This commit is contained in:
parent
b0a3130068
commit
1b170b5562
@ -1,21 +1,47 @@
|
||||
2003-06-22 Paolo Carlini <pcarlini@unitus.it>
|
||||
Nathan C. Myers <ncm-nospam@cantrip.org>
|
||||
|
||||
* include/std/std_streambuf.h (_M_move_out_cur): _M_out_lim
|
||||
is now used only for filebuf, when _M_buf_unified is true.
|
||||
epgtr() plays the role of _M_out_lim but it's only updated
|
||||
upon overflow, underflow, uflow, seekoff/pos.
|
||||
* include/bits/sstream.tcc (_M_underflow): New, implements
|
||||
stringbuf::underflow and uflow.
|
||||
(seekoff, seekpos): Tweak, use _M_update_egptr.
|
||||
* include/std/std_sstream.h (str): Rewrote, deal correctly
|
||||
with the new logic, in particular, when pptr() > egptr().
|
||||
(_M_sync): When __testout && !__testin set all the get area
|
||||
pointers to the current string end.
|
||||
(_M_update_egptr): New, internal function updating egptr()
|
||||
to the actual string end.
|
||||
(_M_underflow): New, declare.
|
||||
(underflow): Dispatch to _M_underflow(false).
|
||||
(uflow): Dispatch to _M_underflow(true).
|
||||
|
||||
* include/bits/sstream.tcc (pbackfail, overflow, seekoff,
|
||||
seekpos): Use only the documented derivation interface to
|
||||
basic_streambuf (gptr(), setg(), etc.) to work right with
|
||||
user specializations.
|
||||
* include/std/std_sstream.h (str, _M_sync): Likewise.
|
||||
|
||||
2003-06-20 Doug Gregor <dgregor@apple.com>
|
||||
|
||||
* testsuite/20_util/auto_ptr.cc: don't dereference NULL auto_ptr
|
||||
* testsuite/21_strings/basic_string/replace/char/4.cc: don't
|
||||
dereference end iterator.
|
||||
* testsuite/21_strings/basic_string/replace/wchar_t/4.cc: same.
|
||||
* testsuite/22_locale/ctype/narrow/char/1.cc: don't subscript with
|
||||
index equal to the length of a string.
|
||||
* testsuite/22_locale/ctype/narrow/char/2.cc: same.
|
||||
* testsuite/22_locale/ctype/narrow/wchar_t/1.cc: same.
|
||||
* testsuite/22_locale/ctype/narrow/wchar_t/2.cc: same.
|
||||
* testsuite/22_locale/ctype/widen/char/1.cc: same.
|
||||
* testsuite/22_locale/ctype/widen/wchar_t/1.cc: same.
|
||||
* testsuite/23_containers/list_modifiers.cc: don't dereference
|
||||
singular reverse iterator.
|
||||
* testsuite/23_containers/vector_bool.cc: don't increment singular
|
||||
iterator.
|
||||
* testsuite/24_iterators/rel_ops.cc: don't compare singular iterator.
|
||||
* testsuite/20_util/auto_ptr.cc: Don't dereference NULL auto_ptr
|
||||
* testsuite/21_strings/basic_string/replace/char/4.cc: Don't
|
||||
dereference end iterator.
|
||||
* testsuite/21_strings/basic_string/replace/wchar_t/4.cc: Same.
|
||||
* testsuite/22_locale/ctype/narrow/char/1.cc: Don't subscript with
|
||||
index equal to the length of a string.
|
||||
* testsuite/22_locale/ctype/narrow/char/2.cc: Same.
|
||||
* testsuite/22_locale/ctype/narrow/wchar_t/1.cc: Same.
|
||||
* testsuite/22_locale/ctype/narrow/wchar_t/2.cc: Same.
|
||||
* testsuite/22_locale/ctype/widen/char/1.cc: Same.
|
||||
* testsuite/22_locale/ctype/widen/wchar_t/1.cc: Same.
|
||||
* testsuite/23_containers/list_modifiers.cc: Don't dereference
|
||||
singular reverse iterator.
|
||||
* testsuite/23_containers/vector_bool.cc: Don't increment singular
|
||||
iterator.
|
||||
* testsuite/24_iterators/rel_ops.cc: Don't compare singular iterator.
|
||||
|
||||
2003-06-20 Doug Gregor <dgregor@apple.com>
|
||||
|
||||
|
@ -49,11 +49,11 @@ namespace std
|
||||
int_type __ret = traits_type::eof();
|
||||
const bool __testeof = traits_type::eq_int_type(__c, __ret);
|
||||
|
||||
if (this->_M_in_beg < this->_M_in_cur)
|
||||
if (this->eback() < this->gptr())
|
||||
{
|
||||
const bool __testeq = traits_type::eq(traits_type::to_char_type(__c),
|
||||
this->_M_in_cur[-1]);
|
||||
--this->_M_in_cur;
|
||||
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.
|
||||
@ -63,7 +63,7 @@ namespace std
|
||||
__ret = traits_type::not_eof(__c);
|
||||
else
|
||||
{
|
||||
*this->_M_in_cur = traits_type::to_char_type(__c);
|
||||
*this->gptr() = traits_type::to_char_type(__c);
|
||||
__ret = __c;
|
||||
}
|
||||
}
|
||||
@ -88,9 +88,9 @@ namespace std
|
||||
// experimental value (pronounced "arbitrary" in some of the
|
||||
// hipper english-speaking countries), and can be changed to
|
||||
// suit particular needs.
|
||||
__size_type __len = std::max(__size_type(_M_string.capacity() + 1),
|
||||
__size_type(512));
|
||||
const bool __testput = this->_M_out_cur < this->_M_out_end;
|
||||
const __size_type __len = std::max(__size_type(_M_string.capacity() + 1),
|
||||
__size_type(512));
|
||||
const bool __testput = this->pptr() < this->epptr();
|
||||
if (__builtin_expect(!__testput && __len > _M_string.max_size(), false))
|
||||
return traits_type::eof();
|
||||
|
||||
@ -103,18 +103,37 @@ namespace std
|
||||
// growth policy builtin into basic_string.
|
||||
__string_type __tmp;
|
||||
__tmp.reserve(__len);
|
||||
__tmp.assign(_M_string.data(),
|
||||
this->_M_out_end - this->_M_out_beg);
|
||||
__tmp.assign(_M_string.data(), this->epptr() - this->pbase());
|
||||
_M_string.swap(__tmp);
|
||||
// Just to be sure...
|
||||
_M_string.reserve(__len);
|
||||
_M_sync(const_cast<char_type*>(_M_string.data()),
|
||||
this->_M_in_cur - this->_M_in_beg,
|
||||
this->_M_out_cur - this->_M_out_beg);
|
||||
this->gptr() - this->eback(),
|
||||
this->pptr() - this->pbase());
|
||||
}
|
||||
return this->sputc(traits_type::to_char_type(__c));
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Alloc>
|
||||
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
|
||||
basic_stringbuf<_CharT, _Traits, _Alloc>::
|
||||
_M_underflow(bool __bump)
|
||||
{
|
||||
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());
|
||||
if (__bump)
|
||||
this->gbump(1);
|
||||
}
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Alloc>
|
||||
typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
|
||||
basic_stringbuf<_CharT, _Traits, _Alloc>::
|
||||
@ -129,35 +148,32 @@ namespace std
|
||||
|
||||
if (_M_string.capacity() && (__testin || __testout || __testboth))
|
||||
{
|
||||
char_type* __beg = __testin ? this->_M_in_beg : this->_M_out_beg;
|
||||
char_type* __beg = __testin ? this->eback() : this->pbase();
|
||||
|
||||
_M_update_egptr();
|
||||
|
||||
off_type __newoffi = 0;
|
||||
off_type __newoffo = 0;
|
||||
if (__way == ios_base::cur)
|
||||
{
|
||||
__newoffi = this->_M_in_cur - __beg;
|
||||
__newoffo = this->_M_out_cur - __beg;
|
||||
__newoffi = this->gptr() - __beg;
|
||||
__newoffo = this->pptr() - __beg;
|
||||
}
|
||||
else if (__way == ios_base::end)
|
||||
{
|
||||
__newoffi = this->_M_in_end - __beg;
|
||||
// Due to the resolution of DR169, ios_base::end
|
||||
// is this->_M_out_lim, not _M_out_end.
|
||||
__newoffo = this->_M_out_lim - __beg;
|
||||
}
|
||||
__newoffo = __newoffi = this->egptr() - __beg;
|
||||
|
||||
if ((__testin || __testboth)
|
||||
&& __newoffi + __off >= 0
|
||||
&& this->_M_in_end - __beg >= __newoffi + __off)
|
||||
&& this->egptr() - __beg >= __newoffi + __off)
|
||||
{
|
||||
this->_M_in_cur = __beg + __newoffi + __off;
|
||||
this->gbump((__beg + __newoffi + __off) - this->gptr());
|
||||
__ret = pos_type(__newoffi);
|
||||
}
|
||||
if ((__testout || __testboth)
|
||||
&& __newoffo + __off >= 0
|
||||
&& this->_M_out_lim - __beg >= __newoffo + __off)
|
||||
&& this->egptr() - __beg >= __newoffo + __off)
|
||||
{
|
||||
this->_M_out_cur = __beg + __newoffo + __off;
|
||||
this->pbump((__beg + __newoffo + __off) - this->pptr());
|
||||
__ret = pos_type(__newoffo);
|
||||
}
|
||||
}
|
||||
@ -176,23 +192,18 @@ namespace std
|
||||
off_type __pos = __sp; // Use streamoff operator to do conversion.
|
||||
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->_M_in_beg : this->_M_out_beg;
|
||||
char_type* __beg = __testin ? this->eback() : this->pbase();
|
||||
|
||||
// NB: Ordered.
|
||||
bool __testposi = false;
|
||||
bool __testposo = false;
|
||||
if (__testin && 0 <= __pos
|
||||
&& __pos <= this->_M_in_end - __beg)
|
||||
__testposi = true;
|
||||
if (__testout && 0 <= __pos
|
||||
&& __pos <= this->_M_out_lim - __beg)
|
||||
__testposo = true;
|
||||
if (__testposi || __testposo)
|
||||
_M_update_egptr();
|
||||
|
||||
const bool __testpos = 0 <= __pos
|
||||
&& __pos <= this->egptr() - __beg;
|
||||
if ((__testin || __testout) && __testpos)
|
||||
{
|
||||
if (__testposi)
|
||||
this->_M_in_cur = __beg + __pos;
|
||||
if (__testposo)
|
||||
this->_M_out_cur = __beg + __pos;
|
||||
if (__testin)
|
||||
this->gbump((__beg + __pos) - this->gptr());
|
||||
if (__testout)
|
||||
this->pbump((__beg + __pos) - this->pptr());
|
||||
__ret = pos_type(off_type(__pos));
|
||||
}
|
||||
}
|
||||
|
@ -133,11 +133,17 @@ namespace std
|
||||
__string_type
|
||||
str() const
|
||||
{
|
||||
__string_type __ret = _M_string;
|
||||
const bool __testout = this->_M_mode & ios_base::out;
|
||||
if (__testout && this->_M_out_beg < this->_M_out_lim)
|
||||
__ret = __string_type(this->_M_out_beg, this->_M_out_lim);
|
||||
return __ret;
|
||||
if (__testout)
|
||||
{
|
||||
// The current egptr() may not be the actual string end.
|
||||
if (this->pptr() > this->egptr())
|
||||
return __string_type(this->pbase(), this->pptr());
|
||||
else
|
||||
return __string_type(this->pbase(), this->egptr());
|
||||
}
|
||||
else
|
||||
return _M_string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,18 +179,18 @@ namespace std
|
||||
_M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
|
||||
}
|
||||
|
||||
// Overridden virtual functions:
|
||||
int_type
|
||||
_M_underflow(bool __bump);
|
||||
|
||||
// [documentation is inherited]
|
||||
virtual int_type
|
||||
underflow()
|
||||
{
|
||||
int_type __ret;
|
||||
if (this->_M_in_cur < this->_M_in_end)
|
||||
__ret = traits_type::to_int_type(*this->_M_in_cur);
|
||||
else
|
||||
__ret = traits_type::eof();
|
||||
return __ret;
|
||||
}
|
||||
{ return _M_underflow(false); }
|
||||
|
||||
// [documentation is inherited]
|
||||
virtual int_type
|
||||
uflow()
|
||||
{ return _M_underflow(true); }
|
||||
|
||||
// [documentation is inherited]
|
||||
virtual int_type
|
||||
@ -250,18 +256,37 @@ namespace std
|
||||
{
|
||||
const bool __testin = this->_M_mode & ios_base::in;
|
||||
const bool __testout = this->_M_mode & ios_base::out;
|
||||
__size_type __len = _M_string.size();
|
||||
const __size_type __len = _M_string.size();
|
||||
|
||||
if (__testin)
|
||||
this->setg(__base, __base + __i, __base + __len);
|
||||
if (__testout)
|
||||
{
|
||||
this->setp(__base, __base + _M_string.capacity());
|
||||
// _M_out_lim points to the string end.
|
||||
this->_M_out_lim += __len;
|
||||
this->_M_out_cur += __o;
|
||||
this->pbump(__o);
|
||||
// We need a pointer to the string end anyway, even when
|
||||
// !__testin: in that case, however, for the correct
|
||||
// functioning of the streambuf inlines all the get area
|
||||
// pointers must be identical.
|
||||
if (!__testin)
|
||||
this->setg(__base + __len, __base + __len, __base + __len);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal function for correctly updating egptr() to the actual
|
||||
// string end.
|
||||
void
|
||||
_M_update_egptr()
|
||||
{
|
||||
const bool __testin = this->_M_mode & ios_base::in;
|
||||
const bool __testout = this->_M_mode & ios_base::out;
|
||||
|
||||
if (__testout && this->pptr() > this->egptr())
|
||||
if (__testin)
|
||||
this->setg(this->eback(), this->gptr(), this->pptr());
|
||||
else
|
||||
this->setg(this->pptr(), this->pptr(), this->pptr());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -238,17 +238,19 @@ namespace std
|
||||
void
|
||||
_M_move_out_cur(off_type __n) // argument needs to be +-
|
||||
{
|
||||
const bool __testin = _M_in_cur;
|
||||
|
||||
_M_out_cur += __n;
|
||||
if (__testin && _M_buf_unified)
|
||||
_M_in_cur += __n;
|
||||
if (_M_out_cur > _M_out_lim)
|
||||
if (__builtin_expect(_M_buf_unified, false))
|
||||
{
|
||||
_M_out_lim = _M_out_cur;
|
||||
// NB: in | out buffers drag the _M_in_end pointer along...
|
||||
const bool __testin = _M_in_cur;
|
||||
if (__testin)
|
||||
_M_in_end += __n;
|
||||
_M_in_cur += __n;
|
||||
if (_M_out_cur > _M_out_lim)
|
||||
{
|
||||
_M_out_lim = _M_out_cur;
|
||||
// NB: in | out buffers drag the _M_in_end pointer along...
|
||||
if (__testin)
|
||||
_M_in_end += __n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user