[libcxx-commits] [PATCH] D138413: [libc++] Enable segmented iterator optimizations for join_view::iterator

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 21 09:59:52 PST 2022


ldionne requested changes to this revision.
ldionne added a comment.
This revision now requires changes to proceed.

This is a neat optimization! I do have some requests for changes, but once those are addressed I think we're on the right track.



================
Comment at: libcxx/include/__iterator/iterator_with_data.h:21
+
+template <class _Iterator, class _Data>
+class __iterator_with_data {
----------------
This is definitely more complicated, but we need to make this an actual iterator.


================
Comment at: libcxx/include/__ranges/join_view.h:72-73
 
-    template<bool> struct __iterator;
-    template<bool> struct __sentinel;
 
----------------
The reason why you're making this change is that otherwise, you can't specialize 

```
template <class ???>
struct __segmented_iterator_traits<???>
```

Naively, one would want to write

```
template <class _View, bool _Const>
struct __segmented_iterator_traits<ranges::join_view<_View>::__iterator<_Const>>
```

but obviously that doesn't work because one cannot specialize on a dependent type, which `__iterator` is. Technically, it would be possible to use a `enable_if` that checks for a nested member of the type (e.g. `__is_join_view_iterator`), but that's not great and it introduces a SFINAE path whenever we instantiate these traits, which is bad for compile-times.

The other option is what you've done here: define the iterator and sentinel types outside of the class. I think that's much better, however it's an ABI break. Fortunately we don't care about this for now because we're still shipping ranges experimentally, but I think we should make this change for all of our existing (and upcoming) views right now to future-proof them.

CC @var-const @huixie90 @Mordante for awareness


================
Comment at: libcxx/include/__ranges/join_view.h:272-273
 
+    _LIBCPP_HIDE_FROM_ABI constexpr __join_view_iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
+      : __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
+
----------------
Can this constructor be private? We don't want to expose non-standard APIs, and this iterator type is public, even though its name isn't public.


================
Comment at: libcxx/include/__ranges/join_view.h:403-404
 
+template <class _View, bool _Const>
+struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> {
+  using _Iterator = ranges::__join_view_iterator<_View, _Const>;
----------------
This would avoid forming a `__segmented_iterator_traits<It>` specialization when it would be nonsensical.


================
Comment at: libcxx/include/__ranges/join_view.h:405
+struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> {
+  using _Iterator = ranges::__join_view_iterator<_View, _Const>;
+
----------------
There's too much iterator-y stuff going on, let's be explicit about this.


================
Comment at: libcxx/include/__ranges/join_view.h:428-430
+    if (!__iter.__inner_.has_value())
+      return ranges::end(*--__iter.__outer_);
+    return *__iter.__inner_;
----------------
Suggestion? I was thrown off by the `*__iter.__inner_;`, I thought you were dereferencing the iterator instead of the optional.


================
Comment at: libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp:124
+template <class Iter, class Sent>
+constexpr void test_join_view() {
+  auto to_subranges = std::views::transform([](auto& vec) {
----------------
I am worried about this test file becoming a mess if we start putting tests for all the segmented iterators here. Could we perhaps extract them to `test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp` instead, along with the `deque` tests?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138413/new/

https://reviews.llvm.org/D138413



More information about the libcxx-commits mailing list