diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 25 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/sstream.tcc | 3 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_algo.h | 47 | ||||
-rw-r--r-- | libstdc++-v3/include/std/std_sstream.h | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc | 58 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc | 58 |
6 files changed, 182 insertions, 17 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e26f127..9509eba 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2004-10-06 Paolo Carlini <pcarlini@suse.de> + + * include/std/std_sstream.h (_M_sync): When the caller is + setbuf, don't trust _M_string.capacity() to be the size of + the buffer area, use _M_string.size() in this case. + * testsuite/27_io/basic_stringbuf/setbuf/char/4.cc: New. + * testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc: Likewise. + + * include/bits/sstream.tcc (overflow): Avoid calling string::assign + unnecessarily when the current _M_string is empty. + +2004-10-06 Paolo Carlini <pcarlini@suse.de> + + * include/bits/stl_algo.h (__reverse(bidirectional_iterator_tag)): + Avoid iterator postincrement. + (__rotate): Likewise. + + * include/bits/stl_algo.h: Minor formatting tweaks. + +2004-10-06 Christopher Jefferson <caj@cs.york.ac.uk> + + * include/bits/stl_algo.h (__reverse(random_access_iterator_tag)): + Avoid iterator postincrement; fix swapping middle element with + itself on odd-length inputs. + 2004-10-05 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/17780 diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc index 985a0e4..86daa6d 100644 --- a/libstdc++-v3/include/bits/sstream.tcc +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -109,7 +109,8 @@ namespace std 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()); + if (this->pbase()) + __tmp.assign(this->pbase(), 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()); diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index a5118c5..658a134 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -1412,29 +1412,39 @@ namespace std template<typename _BidirectionalIterator> void __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, - bidirectional_iterator_tag) + bidirectional_iterator_tag) { while (true) if (__first == __last || __first == --__last) return; else - std::iter_swap(__first++, __last); + { + std::iter_swap(__first, __last); + ++__first; + } } /** * @if maint * This is an uglified reverse(_BidirectionalIterator, * _BidirectionalIterator) - * overloaded for bidirectional iterators. + * overloaded for random access iterators. * @endif */ template<typename _RandomAccessIterator> void __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, - random_access_iterator_tag) + random_access_iterator_tag) { + if (__first == __last) + return; + --__last; while (__first < __last) - std::iter_swap(__first++, --__last); + { + std::iter_swap(__first, __last); + ++__first; + --__last; + } } /** @@ -1454,7 +1464,7 @@ namespace std { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIterator>) + _BidirectionalIterator>) __glibcxx_requires_valid_range(__first, __last); std::__reverse(__first, __last, std::__iterator_category(__first)); } @@ -1525,15 +1535,17 @@ namespace std __rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - forward_iterator_tag) + forward_iterator_tag) { - if ((__first == __middle) || (__last == __middle)) + if (__first == __middle || __last == __middle) return; _ForwardIterator __first2 = __middle; do { - swap(*__first++, *__first2++); + swap(*__first, *__first2); + ++__first; + ++__first2; if (__first == __middle) __middle = __first2; } @@ -1543,7 +1555,9 @@ namespace std while (__first2 != __last) { - swap(*__first++, *__first2++); + swap(*__first, *__first2); + ++__first; + ++__first2; if (__first == __middle) __middle = __first2; else if (__first2 == __last) @@ -1565,16 +1579,19 @@ namespace std { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIterator>) + _BidirectionalIterator>) - if ((__first == __middle) || (__last == __middle)) + if (__first == __middle || __last == __middle) return; std::__reverse(__first, __middle, bidirectional_iterator_tag()); std::__reverse(__middle, __last, bidirectional_iterator_tag()); while (__first != __middle && __middle != __last) - swap(*__first++, *--__last); + { + swap(*__first, *--__last); + ++__first; + } if (__first == __middle) std::__reverse(__middle, __last, bidirectional_iterator_tag()); @@ -1596,9 +1613,9 @@ namespace std { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIterator>) + _RandomAccessIterator>) - if ((__first == __middle) || (__last == __middle)) + if (__first == __middle || __last == __middle) return; typedef typename iterator_traits<_RandomAccessIterator>::difference_type diff --git a/libstdc++-v3/include/std/std_sstream.h b/libstdc++-v3/include/std/std_sstream.h index 3420999..fc4c42a 100644 --- a/libstdc++-v3/include/std/std_sstream.h +++ b/libstdc++-v3/include/std/std_sstream.h @@ -259,7 +259,13 @@ namespace std this->setg(__base, __base + __i, __end); if (__testout) { - this->setp(__base, __base + _M_string.capacity()); + // If __base comes from setbuf we cannot trust capacity() + // to match the size of the buffer area: in general, after + // Step 1 above, _M_string.capacity() >= __n. + if (__base == _M_string.data()) + this->setp(__base, __base + _M_string.capacity()); + else + this->setp(__base, __end); this->pbump(__o); // egptr() always tracks the string end. When !__testin, // for the correct functioning of the streambuf inlines diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc new file mode 100644 index 0000000..0449af2 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc @@ -0,0 +1,58 @@ +// 2004-10-06 Paolo Carlini <pcarlini@suse.de> + +// Copyright (C) 2004 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.8.1.4 Overridden virtual functions + +#include <sstream> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + const unsigned max_size = 1 << 18; + + char ref[max_size]; + memset(ref, '\0', max_size); + + char src[max_size * 2]; + memset(src, '\1', max_size * 2); + + for (unsigned i = 128; i <= max_size; i *= 2) + { + char* dest = new char[i * 2]; + memset(dest, '\0', i * 2); + + stringbuf sbuf; + sbuf.pubsetbuf(dest, i); + + sbuf.sputn(src, i * 2); + VERIFY( !memcmp(dest + i, ref, i) ); + + delete[] dest; + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc new file mode 100644 index 0000000..e0eb8de --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc @@ -0,0 +1,58 @@ +// 2004-10-06 Paolo Carlini <pcarlini@suse.de> + +// Copyright (C) 2004 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.8.1.4 Overridden virtual functions + +#include <sstream> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + const unsigned max_size = 1 << 18; + + wchar_t ref[max_size]; + wmemset(ref, L'\0', max_size); + + wchar_t src[max_size * 2]; + wmemset(src, L'\1', max_size * 2); + + for (unsigned i = 128; i <= max_size; i *= 2) + { + wchar_t* dest = new wchar_t[i * 2]; + wmemset(dest, L'\0', i * 2); + + wstringbuf sbuf; + sbuf.pubsetbuf(dest, i); + + sbuf.sputn(src, i * 2); + VERIFY( !wmemcmp(dest + i, ref, i) ); + + delete[] dest; + } +} + +int main() +{ + test01(); + return 0; +} |