istreambuf_iterator not increment g-pointer of istream, so character will be extracted twice (or more, under some occasion), so it not work as single-pass input iterator: std::stringstream s; char b[] = "c2ee3d09-43b3-466d-b490-db35999a22cf"; char r[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 012345678901234567890123456789012345 s << b; EXAM_CHECK( !s.fail() ); // pass std::copy_n( std::istreambuf_iterator<char>(s), 36, r ); EXAM_CHECK( !s.fail() ); // pass EXAM_CHECK( memcmp(b, r, 36) == 0 ); // pass EXAM_CHECK( s.tellg() == 35 ); // pass ?! char c = 'q'; std::copy_n( std::istreambuf_iterator<char>(s), 1, &c ); EXAM_CHECK( !s.fail() ); // pass ?! EXAM_CHECK( c == 'f' ); // pass ?! EXAM_CHECK( s.tellg() == 35 ); // pass ?!
istreambuf_iterator is specified to call sbumpc() only on increment, not upon construction; the implementation is as specified. The copy_n aspect is https://cplusplus.github.io/LWG/issue2471.
Related problem: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50119, commit 1a1dad283 in git's reflection.
Created attachment 42042 [details] proposed test for issue https://gcc.gnu.org/ml/libstdc++/2017-08/msg00036.html May be worth to add (see issue2471) words to copy_n spec: "copy_n return result + n (i.e. increment OutputIterator n times) and increment InputIterator max(0, n - 1)." to avoid ambiguity?
As TC said, there's nothing wrong with our istreambuf_iterator. Our copy_n is also conforming, due to the poor specification. I don't want to add a test verifying behaviour that might be defective and might change. The "suggested workaround" certainly doesn't belong in our testsuite.