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

            Bug ID: 118647
           Summary: Missed optimization to do memcpy/memmove for
                    contiguous iterator
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: alfredo.correa at gmail dot com
  Target Milestone: ---

I would like to report a missed optimization opportunity for contiguous
iterators in C++20 and up.

I have an iterator that fulfills the contigous_iterator concept and I am trying
to use the copy algorithms.
Naively one would think that the generated code should produce a memmove (or a
memcpy), however 

1) With std::copy the optimization only happens sometimes. That is, the library
is demanding that some iterator operators (op* and op==) be no-except for
actually doing the optimization. That might or might not be a bug, but it
certainly disagrees with libc++.

2) With std::ranges::copy the optimization never happens, which definitely is a
missed opportunity.

This is the illustration of the problem: https://godbolt.org/z/shsvn9oqx (note
the -DNOEX parameter that controls noexcept in the iterator op, (some functions
are not defined so the compile doesn't try to deduce an effective noexcept)

And this the iterator examplar:

```
class cont_iter {
    int* impl_;
public:
    using value_type = int;
    using reference = value_type&;
    using pointer = value_type*;
    using difference_type = std::ptrdiff_t;
    using iterator_concept = std::contiguous_iterator_tag;

    explicit cont_iter();

    int& operator*() const noexcept(NOEX);
    int& operator[](difference_type) const;
    int* operator->() const;

    cont_iter& operator++();
    cont_iter operator++(int);
    cont_iter& operator--();
    cont_iter operator--(int);

    cont_iter& operator+=(difference_type);
    cont_iter& operator-=(difference_type);

    cont_iter operator+(difference_type) const;
    friend cont_iter operator+(difference_type, cont_iter);
    cont_iter operator-(difference_type) const;
    difference_type operator-(cont_iter const&) const;

    std::strong_ordering operator<=>(cont_iter const&) const;
    bool operator==(cont_iter const&) const noexcept(NOEX);
};

static_assert(std::contiguous_iterator<cont_iter>);
```

For context, this is to implement a contiguous iterator in a multidimensional
library, in which under certain parametrizations of the iterator can be deduced
to be contiguous.
Full code here: https://godbolt.org/z/fv7cvbq51

Also, Arthur O'Dwyer and Peter Ditmov helped get to be bottom of this on the
#stl Slack channel.

Reply via email to