This is an archive of the discontinued LLVM Phabricator instance.

[libc++][ranges][NFC] Move iterator classes out of `lazy_split_view` and `zip_view`.
AbandonedPublic

Authored by var-const on Jan 24 2023, 6:24 PM.

Details

Reviewers
ldionne
philnik
Group Reviewers
Restricted Project
Summary

This is part of the work to make it possible specialize traits types for
a view, like __segmented_iterator_traits.

Diff Detail

Event Timeline

var-const created this revision.Jan 24 2023, 6:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 24 2023, 6:24 PM
var-const requested review of this revision.Jan 24 2023, 6:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 24 2023, 6:24 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne accepted this revision.Jan 24 2023, 6:42 PM
ldionne added a subscriber: ldionne.

Do you know whether those are the last ones?

This revision is now accepted and ready to land.Jan 24 2023, 6:42 PM
philnik accepted this revision.Jan 24 2023, 9:49 PM
philnik added a subscriber: philnik.

Do you know whether those are the last ones?

They should be. I've listed the ones that didn't have the iterator outside the class a few weeks ago and these are the last ones.

There is a GCC failure on the CI that exposed two interesting issues:

  1. (Found by @huixie90) Moving iterator classes out of the view class can lead to a noticeable difference in behavior. What was previously template parameters of the view (but not the iterator) becomes template parameters of the iterator. This can add more namespaces and associated classes via ADL when doing overload resolution for the iterator. A Godbolt demo from @huixie90: https://godbolt.org/z/sEzjnnEeK
  1. There is a divergence in behavior between GCC on one side and Clang and MSVC on the other side (https://godbolt.org/z/bbxv75aE7):
template <class T>
concept Foo = requires(T val) {
  val == val;
};

template <class T>
struct Bar {};
template <class T>
bool operator==(const Bar<T>&, const Bar<T>&); // Overload 1

template <class T>
requires Foo<Bar<T>>
bool operator==(const Bar<T>&, int); // Overload 2

static_assert(Foo<Bar<int>>);

In this example, Clang and MSVC would not instantiate overload 2 of operator== when evaluating the Foo concept. GCC, on the other hand, instantiates overload 2 which leads to infinite recursion since overload 2 depends on Foo.

var-const abandoned this revision.Feb 13 2023, 6:39 PM

We ended up deciding to move iterators back into classes -- abandoning in favor of https://reviews.llvm.org/D143324.