This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] libstdc++: test for copy_n/istreambuf_iterator
- From: Petr Ovtchenkov <ptr at void-ptr dot info>
- To: libstdc++ at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 25 Aug 2017 11:47:09 +0300
- Subject: [PATCH] libstdc++: test for copy_n/istreambuf_iterator
- Authentication-results: sourceware.org; auth=none
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