[multiple changes]
authorPaolo Carlini <paolo@gcc.gnu.org>
Wed, 6 Oct 2004 09:06:59 +0000 (09:06 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 6 Oct 2004 09:06:59 +0000 (09:06 +0000)
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.

From-SVN: r88593

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/sstream.tcc
libstdc++-v3/include/bits/stl_algo.h
libstdc++-v3/include/std/std_sstream.h
libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/char/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc [new file with mode: 0644]

index e26f127670e176b93fc71c82bc6e5c3c86fc6d31..9509eba9237a8a43aff1d13ef19df9d061b22d00 100644 (file)
@@ -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
index 985a0e46d07311069024452d2ef9c346c63ba687..86daa6d3ca3149fc4c82df2c02f55ffb04b4a8b4 100644 (file)
@@ -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());
index a5118c57208032fba1d8df783f7cecd2b7adfe3a..658a13435d2e0e31d1f1fff5ae00cd7ea7a4a274 100644 (file)
@@ -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
index 3420999164c09066eee0a6c14efda28c0e95a055..fc4c42a3c7892c3cbfcd21c8e1e268faf29943ab 100644 (file)
@@ -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 (file)
index 0000000..0449af2
--- /dev/null
@@ -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 (file)
index 0000000..e0eb8de
--- /dev/null
@@ -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;
+}