https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119501

            Bug ID: 119501
           Summary: std::ranges::copy_n advances InputIterator one more
                    time than necessary
           Product: gcc
           Version: 14.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: felip_assis at hotmail dot com
  Target Milestone: ---

It seems that the fixed bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50119
reemerged in the Constrained Algorithms library (namespace std::ranges).

This is not a regression, std::copy_n works as expected, but now
std::ranges::copy_n has the issue, making it not only surprising, but also
internally inconsistent.

The problem is that, with istream_iterator, "the actual read operation is
performed when the iterator is incremented, not when it is dereferenced"
(https://en.cppreference.com/w/cpp/iterator/istream_iterator), but the
implementation of std::ranges::copy_n increments the iterator once more than
needed, adding an unexpected read operation. So, while its interface was
carefully planned to allow usage of input iterators, it fails with the
prototypical one, that is part of the standard.

Test program:
```
#include <algorithm>
#include <vector>
#include <sstream>
#include <iterator>
#include <iostream>

int main()
{
  std::istringstream s("1 2 3 4 5");
  std::vector<int> v;
  char c;
  std::istream_iterator<int> it{s};
  std::ranges::copy_n(it, 3, back_inserter(v));
  s >> c;

  copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << c << '\n';
}
```

Compilation:
$ g++ -std=c++23 test.cpp

Output with GCC 14.2.1 (unexpected):
1 2 3 5

Output changing "std::ranges::copy_n" to "std::copy_n" (expected):
1 2 3 4

I admit that I have come up with a robust workaround, but the code is no longer
expressive:
```
  it = std::ranges::copy_n(it, 3 - 1, back_inserter(v)).in;
  v.push_back(*it);
  s >> c;
```

Output of the workaround (expected):
1 2 3 4

Reply via email to