aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog25
-rw-r--r--libstdc++-v3/include/bits/sstream.tcc3
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h47
-rw-r--r--libstdc++-v3/include/std/std_sstream.h8
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc58
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc58
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;
+}