This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] libstdc++: test for copy_n/istreambuf_iterator


copy_n return result + n (i.e. increment OutputIterator n times) and
increment InputIterator max(0, n - 1).

This is issue 81857.

See also https://cplusplus.github.io/LWG/issue2471
---
 .../testsuite/25_algorithms/copy_n/81857.cc        | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc

diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc
new file mode 100644
index 0000000..adb6c35
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/81857.cc
@@ -0,0 +1,83 @@
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2017 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <sstream>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+// libstdc++/81857
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  std::stringstream s;
+  char b[] = "c2ee3d09-43b3-466d-b490-db35999a22cf";
+  char r[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+  //          012345678901234567890123456789012345
+  //          0         1         2         3
+  s << b;
+  VERIFY( !s.fail() );
+
+  VERIFY( s.tellg() == 0 );
+  /*
+    https://cplusplus.github.io/LWG/issue2471
+
+    It's unspecified how many times copy_n increments the InputIterator.
+    uninitialized_copy_n is specified to increment it exactly n times,
+    which means if an istream_iterator is used then the next character
+    after those copied is read from the stream and then discarded, losing data.
+
+    I believe all three of Dinkumware, libc++ and libstdc++ implement copy_n
+    with n - 1 increments of the InputIterator, which avoids reading and
+    discarding a character when used with istream_iterator, but is inconsistent
+    with uninitialized_copy_n and causes surprising behaviour with
+    istreambuf_iterator instead, because copy_n(in, 2, copy_n(in, 2, out))
+    is not equivalent to copy_n(in, 4, out)
+   */
+
+  /*
+    copy_n return result + n (i.e. increment OutputIterator n times) and
+    increment InputIterator max(0, n - 1).
+   */
+  std::copy_n( std::istreambuf_iterator<char>(s), 36, r );
+  VERIFY( !s.fail() );
+  VERIFY( memcmp(b, r, 36) == 0 );
+
+  char c = 'q';
+  std::copy_n( std::istreambuf_iterator<char>(s), 1, &c );
+  VERIFY( std::istreambuf_iterator<char>(s) != std::istreambuf_iterator<char>() ); // see comment above
+  VERIFY( !s.fail() ); // surprise, see comment above
+  VERIFY( c != 'q' );
+  VERIFY( c == 'f' ); // surprise, see comment above
+
+  // Suggested workaround technique:
+  std::istreambuf_iterator<char> iis(s);
+  ++iis; // <---
+  std::copy_n( iis, 1, &c );
+  // VERIFY( s.fail() ); // ?!
+  VERIFY( iis == std::istreambuf_iterator<char>() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
-- 
2.10.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]