[libcxx-commits] [libcxx] 4c2ad19 - [libc++][ranges] move all range iterators back in class

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Feb 11 07:42:30 PST 2023


Author: Hui
Date: 2023-02-11T15:42:08Z
New Revision: 4c2ad195f8c9fe4e3f8a57502d5334d6cbc74f76

URL: https://github.com/llvm/llvm-project/commit/4c2ad195f8c9fe4e3f8a57502d5334d6cbc74f76
DIFF: https://github.com/llvm/llvm-project/commit/4c2ad195f8c9fe4e3f8a57502d5334d6cbc74f76.diff

LOG: [libc++][ranges] move all range iterators back in class

move all range iterators back in class, as out of class iterators
requires extra template parameters, which changes ADL

Differential Revision: https://reviews.llvm.org/D143324

Added: 
    libcxx/test/std/ranges/iterator_robust_against_adl.compile.pass.cpp

Modified: 
    libcxx/include/__ranges/elements_view.h
    libcxx/include/__ranges/filter_view.h
    libcxx/include/__ranges/iota_view.h
    libcxx/include/__ranges/istream_view.h
    libcxx/include/__ranges/split_view.h
    libcxx/include/__ranges/take_while_view.h
    libcxx/include/__ranges/transform_view.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index 3afd6ddbe8f2d..997380ee9c65a 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -49,12 +49,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_iterator;
-
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_sentinel;
-
 template <class _Tp, size_t _Np>
 concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value;
 
@@ -66,6 +60,13 @@ template <input_range _View, size_t _Np>
            __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
            __returnable_element<range_reference_t<_View>, _Np>
 class elements_view : public view_interface<elements_view<_View, _Np>> {
+private:
+  template <bool>
+  class __iterator;
+
+  template <bool>
+  class __sentinel;
+
 public:
   _LIBCPP_HIDE_FROM_ABI elements_view()
     requires default_initializable<_View>
@@ -130,12 +131,6 @@ class elements_view : public view_interface<elements_view<_View, _Np>> {
   }
 
 private:
-  template <bool _Const>
-  using __iterator = __elements_view_iterator<_View, _Np, _Const>;
-
-  template <bool _Const>
-  using __sentinel = __elements_view_sentinel<_View, _Np, _Const>;
-
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
 };
 
@@ -160,13 +155,18 @@ struct __elements_view_iterator_category_base<_Base, _Np> {
   using iterator_category = decltype(__get_iterator_category());
 };
 
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
-  template <class, size_t, bool >
-  friend class __elements_view_iterator;
+template <input_range _View, size_t _Np>
+  requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+           __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+           __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__iterator
+    : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
+  template <bool>
+  friend class __iterator;
 
-  template <class, size_t, bool >
-  friend class __elements_view_sentinel;
+  template <bool>
+  friend class __sentinel;
 
   using _Base = __maybe_const<_Const, _View>;
 
@@ -198,14 +198,13 @@ class __elements_view_iterator : public __elements_view_iterator_category_base<_
   using value_type       = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;
   using 
diff erence_type  = range_
diff erence_t<_Base>;
 
-  _LIBCPP_HIDE_FROM_ABI __elements_view_iterator()
+  _LIBCPP_HIDE_FROM_ABI __iterator()
     requires default_initializable<iterator_t<_Base>>
   = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_iterator(iterator_t<_Base> __current)
-      : __current_(std::move(__current)) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator(__elements_view_iterator<_View, _Np, !_Const> __i)
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
     requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
       : __current_(std::move(__i.__current_)) {}
 
@@ -215,14 +214,14 @@ class __elements_view_iterator : public __elements_view_iterator_category_base<_
 
   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator++() {
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
     ++__current_;
     return *this;
   }
 
   _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator++(int)
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
     requires forward_range<_Base>
   {
     auto temp = *this;
@@ -230,14 +229,14 @@ class __elements_view_iterator : public __elements_view_iterator_category_base<_
     return temp;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator--()
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
     requires bidirectional_range<_Base>
   {
     --__current_;
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator--(int)
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
     requires bidirectional_range<_Base>
   {
     auto temp = *this;
@@ -245,14 +244,14 @@ class __elements_view_iterator : public __elements_view_iterator_category_base<_
     return temp;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator+=(
diff erence_type __n)
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(
diff erence_type __n)
     requires random_access_range<_Base>
   {
     __current_ += __n;
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator-=(
diff erence_type __n)
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(
diff erence_type __n)
     requires random_access_range<_Base>
   {
     __current_ -= __n;
@@ -265,99 +264,91 @@ class __elements_view_iterator : public __elements_view_iterator_category_base<_
     return __get_element(__current_ + __n);
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
     requires equality_comparable<iterator_t<_Base>>
   {
     return __x.__current_ == __y.__current_;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator<(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __x.__current_ < __y.__current_;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __y < __x;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator<=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return !(__y < __x);
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator>=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return !(__x < __y);
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr auto
-  operator<=>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
   {
     return __x.__current_ <=> __y.__current_;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
-  operator+(const __elements_view_iterator& __x, 
diff erence_type __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, 
diff erence_type __y)
     requires random_access_range<_Base>
   {
-    return __elements_view_iterator{__x} += __y;
+    return __iterator{__x} += __y;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
-  operator+(
diff erence_type __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(
diff erence_type __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __y + __x;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
-  operator-(const __elements_view_iterator& __x, 
diff erence_type __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, 
diff erence_type __y)
     requires random_access_range<_Base>
   {
-    return __elements_view_iterator{__x} -= __y;
+    return __iterator{__x} -= __y;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr 
diff erence_type
-  operator-(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr 
diff erence_type operator-(const __iterator& __x, const __iterator& __y)
     requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
   {
     return __x.__current_ - __y.__current_;
   }
 };
 
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_sentinel {
+template <input_range _View, size_t _Np>
+  requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+           __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+           __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__sentinel {
 private:
   using _Base                                        = __maybe_const<_Const, _View>;
   _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
 
-  template <class, size_t, bool >
-  friend class __elements_view_sentinel;
+  template <bool>
+  friend class __sentinel;
 
   template <bool _AnyConst>
-  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
-  __get_current(const __elements_view_iterator<_View, _Np, _AnyConst>& __iter) {
+  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) {
     return (__iter.__current_);
   }
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __elements_view_sentinel() = default;
+  _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_sentinel(sentinel_t<_Base> __end)
-      : __end_(std::move(__end)) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_sentinel(__elements_view_sentinel<_View, _Np, !_Const> __other)
+  _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other)
     requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
       : __end_(std::move(__other.__end_)) {}
 
@@ -365,22 +356,21 @@ class __elements_view_sentinel {
 
   template <bool _OtherConst>
     requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
     return __get_current(__x) == __y.__end_;
   }
 
   template <bool _OtherConst>
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI friend constexpr range_
diff erence_t<__maybe_const<_OtherConst, _View>>
-  operator-(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+  operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
     return __get_current(__x) - __y.__end_;
   }
 
   template <bool _OtherConst>
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI friend constexpr range_
diff erence_t<__maybe_const<_OtherConst, _View>>
-  operator-(const __elements_view_sentinel& __x, const __elements_view_iterator<_View, _Np, _OtherConst>& __y) {
+  operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
     return __x.__end_ - __get_current(__y);
   }
 };

diff  --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
index f8633a3fee843..e14a9abeb9e7b 100644
--- a/libcxx/include/__ranges/filter_view.h
+++ b/libcxx/include/__ranges/filter_view.h
@@ -46,15 +46,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER > 17
 
 namespace ranges {
-
-  template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
-    requires view<_View> && is_object_v<_Pred>
-  class __filter_view_iterator;
-
-  template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
-    requires view<_View> && is_object_v<_Pred>
-  class __filter_view_sentinel;
-
   template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
     requires view<_View> && is_object_v<_Pred>
   class filter_view : public view_interface<filter_view<_View, _Pred>> {
@@ -67,11 +58,8 @@ namespace ranges {
     using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
     _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
 
-    using __iterator = __filter_view_iterator<_View, _Pred>;
-    using __sentinel = __filter_view_sentinel<_View, _Pred>;
-
-    friend __iterator;
-    friend __sentinel;
+    class __iterator;
+    class __sentinel;
 
   public:
     _LIBCPP_HIDE_FROM_ABI
@@ -131,13 +119,11 @@ namespace ranges {
 
   template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
     requires view<_View> && is_object_v<_Pred>
-  class __filter_view_iterator : public __filter_iterator_category<_View> {
-
-    using __filter_view = filter_view<_View, _Pred>;
+  class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
 
   public:
     _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
-    _LIBCPP_NO_UNIQUE_ADDRESS __filter_view* __parent_ = nullptr;
+    _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
 
     using iterator_concept =
       _If<bidirectional_range<_View>, bidirectional_iterator_tag,
@@ -149,10 +135,10 @@ namespace ranges {
     using 
diff erence_type = range_
diff erence_t<_View>;
 
     _LIBCPP_HIDE_FROM_ABI
-    __filter_view_iterator() requires default_initializable<iterator_t<_View>> = default;
+    __iterator() requires default_initializable<iterator_t<_View>> = default;
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr __filter_view_iterator(__filter_view& __parent, iterator_t<_View> __current)
+    constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
       : __current_(std::move(__current)), __parent_(std::addressof(__parent))
     { }
 
@@ -171,7 +157,7 @@ namespace ranges {
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr __filter_view_iterator& operator++() {
+    constexpr __iterator& operator++() {
       __current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_),
                                    std::ref(*__parent_->__pred_));
       return *this;
@@ -179,42 +165,42 @@ namespace ranges {
     _LIBCPP_HIDE_FROM_ABI
     constexpr void operator++(int) { ++*this; }
     _LIBCPP_HIDE_FROM_ABI
-    constexpr __filter_view_iterator operator++(int) requires forward_range<_View> {
+    constexpr __iterator operator++(int) requires forward_range<_View> {
       auto __tmp = *this;
       ++*this;
       return __tmp;
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr __filter_view_iterator& operator--() requires bidirectional_range<_View> {
+    constexpr __iterator& operator--() requires bidirectional_range<_View> {
       do {
         --__current_;
       } while (!std::invoke(*__parent_->__pred_, *__current_));
       return *this;
     }
     _LIBCPP_HIDE_FROM_ABI
-    constexpr __filter_view_iterator operator--(int) requires bidirectional_range<_View> {
+    constexpr __iterator operator--(int) requires bidirectional_range<_View> {
       auto tmp = *this;
       --*this;
       return tmp;
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator==(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
+    friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
       requires equality_comparable<iterator_t<_View>>
     {
       return __x.__current_ == __y.__current_;
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    friend constexpr range_rvalue_reference_t<_View> iter_move(__filter_view_iterator const& __it)
+    friend constexpr range_rvalue_reference_t<_View> iter_move(__iterator const& __it)
       noexcept(noexcept(ranges::iter_move(__it.__current_)))
     {
       return ranges::iter_move(__it.__current_);
     }
 
     _LIBCPP_HIDE_FROM_ABI
-    friend constexpr void iter_swap(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
+    friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y)
       noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
       requires indirectly_swappable<iterator_t<_View>>
     {
@@ -224,17 +210,15 @@ namespace ranges {
 
   template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
     requires view<_View> && is_object_v<_Pred>
-  class __filter_view_sentinel {
-    using __filter_view = filter_view<_View, _Pred>;
-
+  class filter_view<_View, _Pred>::__sentinel {
   public:
     sentinel_t<_View> __end_ = sentinel_t<_View>();
 
     _LIBCPP_HIDE_FROM_ABI
-    __filter_view_sentinel() = default;
+    __sentinel() = default;
 
     _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __filter_view_sentinel(__filter_view& __parent)
+    constexpr explicit __sentinel(filter_view& __parent)
       : __end_(ranges::end(__parent.__base_))
     { }
 
@@ -242,7 +226,7 @@ namespace ranges {
     constexpr sentinel_t<_View> base() const { return __end_; }
 
     _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-    operator==(__filter_view_iterator<_View, _Pred> const& __x, __filter_view_sentinel const& __y) {
+    operator==(__iterator const& __x, __sentinel const& __y) {
       return __x.__current_ == __y.__end_;
     }
   };

diff  --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 3654096b7e174..8f9148a6849cb 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -83,14 +83,6 @@ namespace ranges {
       { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
     };
 
-  template <weakly_incrementable _Start>
-    requires copyable<_Start>
-  struct __iota_view_iterator;
-
-  template <weakly_incrementable _Start, semiregular _BoundSentinel>
-    requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
-  struct __iota_view_sentinel;
-
   template<class>
   struct __iota_iterator_category {};
 
@@ -102,9 +94,211 @@ namespace ranges {
   template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
     requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
   class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
+    struct __iterator : public __iota_iterator_category<_Start> {
+      friend class iota_view;
+
+      using iterator_concept =
+        _If<__advanceable<_Start>,   random_access_iterator_tag,
+        _If<__decrementable<_Start>, bidirectional_iterator_tag,
+        _If<incrementable<_Start>,   forward_iterator_tag,
+        /*Else*/                     input_iterator_tag>>>;
+
+      using value_type = _Start;
+      using 
diff erence_type = _IotaDiffT<_Start>;
+
+      _Start __value_ = _Start();
+
+      _LIBCPP_HIDE_FROM_ABI
+      __iterator() requires default_initializable<_Start> = default;
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
+        return __value_;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator& operator++() {
+        ++__value_;
+        return *this;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr void operator++(int) { ++*this; }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator operator++(int) requires incrementable<_Start> {
+        auto __tmp = *this;
+        ++*this;
+        return __tmp;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator& operator--() requires __decrementable<_Start> {
+        --__value_;
+        return *this;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator  operator--(int) requires __decrementable<_Start> {
+        auto __tmp = *this;
+        --*this;
+        return __tmp;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator& operator+=(
diff erence_type __n)
+        requires __advanceable<_Start>
+      {
+        if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+          if (__n >= 
diff erence_type(0)) {
+            __value_ += static_cast<_Start>(__n);
+          } else {
+            __value_ -= static_cast<_Start>(-__n);
+          }
+        } else {
+          __value_ += __n;
+        }
+        return *this;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr __iterator& operator-=(
diff erence_type __n)
+        requires __advanceable<_Start>
+      {
+        if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+          if (__n >= 
diff erence_type(0)) {
+            __value_ -= static_cast<_Start>(__n);
+          } else {
+            __value_ += static_cast<_Start>(-__n);
+          }
+        } else {
+          __value_ -= __n;
+        }
+        return *this;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      constexpr _Start operator[](
diff erence_type __n) const
+        requires __advanceable<_Start>
+      {
+        return _Start(__value_ + __n);
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+        requires equality_comparable<_Start>
+      {
+        return __x.__value_ == __y.__value_;
+      }
 
-    using __iterator = __iota_view_iterator<_Start>;
-    using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>;
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+        requires totally_ordered<_Start>
+      {
+        return __x.__value_ < __y.__value_;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+        requires totally_ordered<_Start>
+      {
+        return __y < __x;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+        requires totally_ordered<_Start>
+      {
+        return !(__y < __x);
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+        requires totally_ordered<_Start>
+      {
+        return !(__x < __y);
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+        requires totally_ordered<_Start> && three_way_comparable<_Start>
+      {
+        return __x.__value_ <=> __y.__value_;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr __iterator operator+(__iterator __i, 
diff erence_type __n)
+        requires __advanceable<_Start>
+      {
+        __i += __n;
+        return __i;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr __iterator operator+(
diff erence_type __n, __iterator __i)
+        requires __advanceable<_Start>
+      {
+        return __i + __n;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr __iterator operator-(__iterator __i, 
diff erence_type __n)
+        requires __advanceable<_Start>
+      {
+        __i -= __n;
+        return __i;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr 
diff erence_type operator-(const __iterator& __x, const __iterator& __y)
+        requires __advanceable<_Start>
+      {
+        if constexpr (__integer_like<_Start>) {
+          if constexpr (__signed_integer_like<_Start>) {
+            return 
diff erence_type(
diff erence_type(__x.__value_) - 
diff erence_type(__y.__value_));
+          }
+          if (__y.__value_ > __x.__value_) {
+            return 
diff erence_type(-
diff erence_type(__y.__value_ - __x.__value_));
+          }
+          return 
diff erence_type(__x.__value_ - __y.__value_);
+        }
+        return __x.__value_ - __y.__value_;
+      }
+    };
+
+    struct __sentinel {
+      friend class iota_view;
+
+    private:
+      _BoundSentinel __bound_sentinel_ = _BoundSentinel();
+
+    public:
+      _LIBCPP_HIDE_FROM_ABI
+      __sentinel() = default;
+      constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
+        return __x.__value_ == __y.__bound_sentinel_;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr iter_
diff erence_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
+        requires sized_sentinel_for<_BoundSentinel, _Start>
+      {
+        return __x.__value_ - __y.__bound_sentinel_;
+      }
+
+      _LIBCPP_HIDE_FROM_ABI
+      friend constexpr iter_
diff erence_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
+        requires sized_sentinel_for<_BoundSentinel, _Start>
+      {
+        return -(__y - __x);
+      }
+    };
 
     _Start __value_ = _Start();
     _BoundSentinel __bound_sentinel_ = _BoundSentinel();
@@ -185,224 +379,6 @@ namespace ranges {
   template <class _Start, class _BoundSentinel>
   inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
 
-  template <weakly_incrementable _Start>
-    requires copyable<_Start>
-  struct __iota_view_iterator : public __iota_iterator_category<_Start> {
-
-    template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
-      requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
-    friend class iota_view;
-
-    using iterator_concept =
-      _If<__advanceable<_Start>,   random_access_iterator_tag,
-      _If<__decrementable<_Start>, bidirectional_iterator_tag,
-      _If<incrementable<_Start>,   forward_iterator_tag,
-      /*Else*/                     input_iterator_tag>>>;
-
-    using value_type = _Start;
-    using 
diff erence_type = _IotaDiffT<_Start>;
-
-    _Start __value_ = _Start();
-
-    _LIBCPP_HIDE_FROM_ABI
-    __iota_view_iterator() requires default_initializable<_Start> = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __iota_view_iterator(_Start __value) : __value_(std::move(__value)) {}
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
-      return __value_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator& operator++() {
-      ++__value_;
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr void operator++(int) { ++*this; }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator operator++(int) requires incrementable<_Start> {
-      auto __tmp = *this;
-      ++*this;
-      return __tmp;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator& operator--() requires __decrementable<_Start> {
-      --__value_;
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator  operator--(int) requires __decrementable<_Start> {
-      auto __tmp = *this;
-      --*this;
-      return __tmp;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator& operator+=(
diff erence_type __n)
-      requires __advanceable<_Start>
-    {
-      if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
-        if (__n >= 
diff erence_type(0)) {
-          __value_ += static_cast<_Start>(__n);
-        } else {
-          __value_ -= static_cast<_Start>(-__n);
-        }
-      } else {
-        __value_ += __n;
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __iota_view_iterator& operator-=(
diff erence_type __n)
-      requires __advanceable<_Start>
-    {
-      if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
-        if (__n >= 
diff erence_type(0)) {
-          __value_ -= static_cast<_Start>(__n);
-        } else {
-          __value_ += static_cast<_Start>(-__n);
-        }
-      } else {
-        __value_ -= __n;
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Start operator[](
diff erence_type __n) const
-      requires __advanceable<_Start>
-    {
-      return _Start(__value_ + __n);
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator==(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires equality_comparable<_Start>
-    {
-      return __x.__value_ == __y.__value_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator<(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires totally_ordered<_Start>
-    {
-      return __x.__value_ < __y.__value_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires totally_ordered<_Start>
-    {
-      return __y < __x;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator<=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires totally_ordered<_Start>
-    {
-      return !(__y < __x);
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator>=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires totally_ordered<_Start>
-    {
-      return !(__x < __y);
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr auto operator<=>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires totally_ordered<_Start> && three_way_comparable<_Start>
-    {
-      return __x.__value_ <=> __y.__value_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr __iota_view_iterator operator+(__iota_view_iterator __i, 
diff erence_type __n)
-      requires __advanceable<_Start>
-    {
-      __i += __n;
-      return __i;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr __iota_view_iterator operator+(
diff erence_type __n, __iota_view_iterator __i)
-      requires __advanceable<_Start>
-    {
-      return __i + __n;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr __iota_view_iterator operator-(__iota_view_iterator __i, 
diff erence_type __n)
-      requires __advanceable<_Start>
-    {
-      __i -= __n;
-      return __i;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr 
diff erence_type operator-(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
-      requires __advanceable<_Start>
-    {
-      if constexpr (__integer_like<_Start>) {
-        if constexpr (__signed_integer_like<_Start>) {
-          return 
diff erence_type(
diff erence_type(__x.__value_) - 
diff erence_type(__y.__value_));
-        }
-        if (__y.__value_ > __x.__value_) {
-          return 
diff erence_type(-
diff erence_type(__y.__value_ - __x.__value_));
-        }
-        return 
diff erence_type(__x.__value_ - __y.__value_);
-      }
-      return __x.__value_ - __y.__value_;
-    }
-  };
-
-  template <weakly_incrementable _Start, semiregular _BoundSentinel>
-    requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
-  struct __iota_view_sentinel {
-
-    template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
-      requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
-    friend class iota_view;
-
-    using __iterator = __iota_view_iterator<_Start>;
-
-  private:
-    _BoundSentinel __bound_sentinel_ = _BoundSentinel();
-
-  public:
-    _LIBCPP_HIDE_FROM_ABI
-    __iota_view_sentinel() = default;
-    constexpr explicit __iota_view_sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr bool operator==(const __iterator& __x, const __iota_view_sentinel& __y) {
-      return __x.__value_ == __y.__bound_sentinel_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr iter_
diff erence_t<_Start> operator-(const __iterator& __x, const __iota_view_sentinel& __y)
-      requires sized_sentinel_for<_BoundSentinel, _Start>
-    {
-      return __x.__value_ - __y.__bound_sentinel_;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    friend constexpr iter_
diff erence_t<_Start> operator-(const __iota_view_sentinel& __x, const __iterator& __y)
-      requires sized_sentinel_for<_BoundSentinel, _Start>
-    {
-      return -(__y - __x);
-    }
-  };
-
  namespace views {
  namespace __iota {
   struct __fn {

diff  --git a/libcxx/include/__ranges/istream_view.h b/libcxx/include/__ranges/istream_view.h
index 69a9df35a4d29..66cd91527616a 100644
--- a/libcxx/include/__ranges/istream_view.h
+++ b/libcxx/include/__ranges/istream_view.h
@@ -36,18 +36,10 @@ namespace ranges {
 template <class _Val, class _CharT, class _Traits>
 concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; };
 
-template <movable _Val, class _CharT, class _Traits>
-  requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
-class __basic_istream_view_iterator;
-
 template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
   requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
 class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
-  using __iterator = __basic_istream_view_iterator<_Val, _CharT, _Traits>;
-
-  template <movable _ValueType, class _CharType, class _TraitsType>
-    requires default_initializable<_ValueType> && __stream_extractable<_ValueType, _CharType, _TraitsType>
-  friend class __basic_istream_view_iterator;
+  class __iterator;
 
 public:
   _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
@@ -67,23 +59,23 @@ class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT
 
 template <movable _Val, class _CharT, class _Traits>
   requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
-class __basic_istream_view_iterator {
+class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
 public:
   using iterator_concept = input_iterator_tag;
   using 
diff erence_type  = ptr
diff _t;
   using value_type       = _Val;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __basic_istream_view_iterator(
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
       basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
       : __parent_(std::addressof(__parent)) {}
 
-  __basic_istream_view_iterator(const __basic_istream_view_iterator&)                  = delete;
-  _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator(__basic_istream_view_iterator&&) = default;
+  __iterator(const __iterator&)                  = delete;
+  _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
 
-  __basic_istream_view_iterator& operator=(const __basic_istream_view_iterator&)                  = delete;
-  _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator=(__basic_istream_view_iterator&&) = default;
+  __iterator& operator=(const __iterator&)                  = delete;
+  _LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default;
 
-  _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator++() {
+  _LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
     *__parent_->__stream_ >> __parent_->__value_;
     return *this;
   }
@@ -92,7 +84,7 @@ class __basic_istream_view_iterator {
 
   _LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; }
 
-  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __basic_istream_view_iterator& __x, default_sentinel_t) {
+  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __x, default_sentinel_t) {
     return !*__x.__get_parent_stream();
   }
 

diff  --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h
index 9758ee935f299..6ebe5a43ed228 100644
--- a/libcxx/include/__ranges/split_view.h
+++ b/libcxx/include/__ranges/split_view.h
@@ -42,12 +42,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace ranges {
 
-template <class _View, class _Pattern>
-struct __split_view_iterator;
-
-template <class _View, class _Pattern>
-struct __split_view_sentinel;
-
 template <forward_range _View, forward_range _Pattern>
   requires view<_View> && view<_Pattern> &&
            indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
@@ -59,13 +53,13 @@ class split_view : public view_interface<split_view<_View, _Pattern>> {
   _Cache __cached_begin_                        = _Cache();
 
   template <class, class>
-  friend struct __split_view_iterator;
+  friend struct __iterator;
 
   template <class, class>
-  friend struct __split_view_sentinel;
+  friend struct __sentinel;
 
-  using __iterator = __split_view_iterator<_View, _Pattern>;
-  using __sentinel = __split_view_sentinel<_View, _Pattern>;
+  struct __iterator;
+  struct __sentinel;
 
   _LIBCPP_HIDE_FROM_ABI constexpr subrange<iterator_t<_View>> __find_next(iterator_t<_View> __it) {
     auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_);
@@ -120,16 +114,17 @@ split_view(_Range&&, _Pattern&&) -> split_view<views::all_t<_Range>, views::all_
 template <forward_range _Range>
 split_view(_Range&&, range_value_t<_Range>) -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
 
-template <class _View, class _Pattern>
-struct __split_view_iterator {
+template <forward_range _View, forward_range _Pattern>
+  requires view<_View> && view<_Pattern> &&
+           indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__iterator {
 private:
-  split_view<_View, _Pattern>* __parent_                        = nullptr;
+  split_view* __parent_                                         = nullptr;
   _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_            = iterator_t<_View>();
   _LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
   bool __trailing_empty_                                        = false;
 
-  template <class, class>
-  friend struct __split_view_sentinel;
+  friend struct __sentinel;
 
 public:
   using iterator_concept  = forward_iterator_tag;
@@ -137,9 +132,9 @@ struct __split_view_iterator {
   using value_type        = subrange<iterator_t<_View>>;
   using 
diff erence_type   = range_
diff erence_t<_View>;
 
-  _LIBCPP_HIDE_FROM_ABI __split_view_iterator() = default;
+  _LIBCPP_HIDE_FROM_ABI __iterator() = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator(
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator(
       split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange<iterator_t<_View>> __next)
       : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
 
@@ -147,7 +142,7 @@ struct __split_view_iterator {
 
   _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator& operator++() {
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
     __cur_ = __next_.begin();
     if (__cur_ != ranges::end(__parent_->__base_)) {
       __cur_ = __next_.end();
@@ -163,36 +158,35 @@ struct __split_view_iterator {
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator operator++(int) {
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
     auto __tmp = *this;
     ++*this;
     return __tmp;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const __split_view_iterator& __x, const __split_view_iterator& __y) {
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
     return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_;
   }
 };
 
-template <class _View, class _Pattern>
-struct __split_view_sentinel {
+template <forward_range _View, forward_range _Pattern>
+  requires view<_View> && view<_Pattern> &&
+           indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__sentinel {
 private:
   _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
 
-  _LIBCPP_HIDE_FROM_ABI static constexpr bool
-  __equals(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+  _LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) {
     return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
   }
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __split_view_sentinel() = default;
+  _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __split_view_sentinel(split_view<_View, _Pattern>& __parent)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent)
       : __end_(ranges::end(__parent.__base_)) {}
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
     return __equals(__x, __y);
   }
 };

diff  --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h
index 59c0a4f82889a..77d7390dceb9c 100644
--- a/libcxx/include/__ranges/take_while_view.h
+++ b/libcxx/include/__ranges/take_while_view.h
@@ -53,17 +53,11 @@ template <class _View, class _Pred>
 concept __take_while_const_is_range =
     range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>;
 
-template <class, class, bool>
-class __take_while_view_sentinel;
-
 template <view _View, class _Pred>
   requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
 class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
-  template <class, class, bool>
-  friend class __take_while_view_sentinel;
-
-  template <bool _Const>
-  using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>;
+  template <bool>
+  class __sentinel;
 
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
   _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
@@ -114,37 +108,37 @@ class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
 template <class _Range, class _Pred>
 take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>;
 
-template <class _View, class _Pred, bool _Const>
-class __take_while_view_sentinel {
+template <view _View, class _Pred>
+  requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
+template <bool _Const>
+class take_while_view<_View, _Pred>::__sentinel {
   using _Base = __maybe_const<_Const, _View>;
 
   sentinel_t<_Base> __end_ = sentinel_t<_Base>();
   const _Pred* __pred_     = nullptr;
 
-  template <class, class, bool>
-  friend class __take_while_view_sentinel;
+  friend class __sentinel<!_Const>;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __take_while_view_sentinel() = default;
+  _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
 
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit __take_while_view_sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
       : __end_(std::move(__end)), __pred_(__pred) {}
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __take_while_view_sentinel(__take_while_view_sentinel<_View, _Pred, !_Const> __s)
+  _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
     requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
       : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {}
 
   _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const iterator_t<_Base>& __x, const __take_while_view_sentinel& __y) {
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) {
     return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
   }
 
   template <bool _OtherConst = !_Const>
     requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI friend constexpr bool
-  operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __take_while_view_sentinel& __y) {
+  operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) {
     return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
   }
 };

diff  --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index ebdff77a7fec6..7f0735b86bbf6 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -57,31 +57,11 @@ concept __transform_view_constraints =
   regular_invocable<_Fn&, range_reference_t<_View>> &&
   __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
 
-template <input_range _View, copy_constructible _Function, bool _IsConst>
-  requires __transform_view_constraints<_View, _Function>
-class __transform_view_iterator;
-
-template <input_range _View, copy_constructible _Function, bool _IsConst>
-  requires __transform_view_constraints<_View, _Function>
-class __transform_view_sentinel;
-
 template<input_range _View, copy_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
 class transform_view : public view_interface<transform_view<_View, _Fn>> {
-
-  template <bool _IsConst>
-  using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
-
-  template <bool _IsConst>
-  using __sentinel = __transform_view_sentinel<_View, _Fn, _IsConst>;
-
-  template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_iterator;
-
-  template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_sentinel;
+  template<bool> class __iterator;
+  template<bool> class __sentinel;
 
   _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
@@ -176,23 +156,22 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
   >;
 };
 
-template<input_range _View, copy_constructible _Fn, bool _Const>
+template<input_range _View, copy_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
-class __transform_view_iterator
+template<bool _Const>
+class transform_view<_View, _Fn>::__iterator
   : public __transform_view_iterator_category_base<_View, _Fn> {
 
-  using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
+  using _Parent = __maybe_const<_Const, transform_view>;
   using _Base = __maybe_const<_Const, _View>;
 
   _Parent *__parent_ = nullptr;
 
-  template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_iterator;
+  template<bool>
+  friend class transform_view<_View, _Fn>::__iterator;
 
-  template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_sentinel;
+  template<bool>
+  friend class transform_view<_View, _Fn>::__sentinel;
 
 public:
   iterator_t<_Base> __current_ = iterator_t<_Base>();
@@ -202,17 +181,17 @@ class __transform_view_iterator
   using 
diff erence_type = range_
diff erence_t<_Base>;
 
   _LIBCPP_HIDE_FROM_ABI
-  __transform_view_iterator() requires default_initializable<iterator_t<_Base>> = default;
+  __iterator() requires default_initializable<iterator_t<_Base>> = default;
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator(_Parent& __parent, iterator_t<_Base> __current)
+  constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
     : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
 
-  // Note: `__i` should always be `__transform_view_iterator<false>`, but directly using
-  // `__transform_view_iterator<false>` is ill-formed when `_Const` is false
+  // Note: `__i` should always be `__iterator<false>`, but directly using
+  // `__iterator<false>` is ill-formed when `_Const` is false
   // (see http://wg21.link/class.copy.ctor#5).
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator(__transform_view_iterator<_View, _Fn, !_Const> __i)
+  constexpr __iterator(__iterator<!_Const> __i)
     requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
     : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
 
@@ -234,7 +213,7 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator& operator++() {
+  constexpr __iterator& operator++() {
     ++__current_;
     return *this;
   }
@@ -243,7 +222,7 @@ class __transform_view_iterator
   constexpr void operator++(int) { ++__current_; }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator operator++(int)
+  constexpr __iterator operator++(int)
     requires forward_range<_Base>
   {
     auto __tmp = *this;
@@ -252,7 +231,7 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator& operator--()
+  constexpr __iterator& operator--()
     requires bidirectional_range<_Base>
   {
     --__current_;
@@ -260,7 +239,7 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator operator--(int)
+  constexpr __iterator operator--(int)
     requires bidirectional_range<_Base>
   {
     auto __tmp = *this;
@@ -269,7 +248,7 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator& operator+=(
diff erence_type __n)
+  constexpr __iterator& operator+=(
diff erence_type __n)
     requires random_access_range<_Base>
   {
     __current_ += __n;
@@ -277,7 +256,7 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_iterator& operator-=(
diff erence_type __n)
+  constexpr __iterator& operator-=(
diff erence_type __n)
     requires random_access_range<_Base>
   {
     __current_ -= __n;
@@ -293,77 +272,77 @@ class __transform_view_iterator
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator==(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
     requires equality_comparable<iterator_t<_Base>>
   {
     return __x.__current_ == __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator<(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __x.__current_ < __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __x.__current_ > __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator<=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __x.__current_ <= __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator>=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base>
   {
     return __x.__current_ >= __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr auto operator<=>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
     requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
   {
     return __x.__current_ <=> __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr __transform_view_iterator operator+(__transform_view_iterator __i, 
diff erence_type __n)
+  friend constexpr __iterator operator+(__iterator __i, 
diff erence_type __n)
     requires random_access_range<_Base>
   {
-    return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
+    return __iterator{*__i.__parent_, __i.__current_ + __n};
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr __transform_view_iterator operator+(
diff erence_type __n, __transform_view_iterator __i)
+  friend constexpr __iterator operator+(
diff erence_type __n, __iterator __i)
     requires random_access_range<_Base>
   {
-    return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
+    return __iterator{*__i.__parent_, __i.__current_ + __n};
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr __transform_view_iterator operator-(__transform_view_iterator __i, 
diff erence_type __n)
+  friend constexpr __iterator operator-(__iterator __i, 
diff erence_type __n)
     requires random_access_range<_Base>
   {
-    return __transform_view_iterator{*__i.__parent_, __i.__current_ - __n};
+    return __iterator{*__i.__parent_, __i.__current_ - __n};
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr 
diff erence_type operator-(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+  friend constexpr 
diff erence_type operator-(const __iterator& __x, const __iterator& __y)
     requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
   {
     return __x.__current_ - __y.__current_;
   }
 
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr decltype(auto) iter_move(const __transform_view_iterator& __i)
+  friend constexpr decltype(auto) iter_move(const __iterator& __i)
     noexcept(noexcept(*__i))
   {
     if constexpr (is_lvalue_reference_v<decltype(*__i)>)
@@ -373,37 +352,33 @@ class __transform_view_iterator
   }
 };
 
-template<input_range _View, copy_constructible _Fn, bool _Const>
+template<input_range _View, copy_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
-class __transform_view_sentinel {
-  using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
+template<bool _Const>
+class transform_view<_View, _Fn>::__sentinel {
+  using _Parent = __maybe_const<_Const, transform_view>;
   using _Base = __maybe_const<_Const, _View>;
 
-  template <bool _IsConst>
-  using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
-
   sentinel_t<_Base> __end_ = sentinel_t<_Base>();
 
-  template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_iterator;
+  template<bool>
+  friend class transform_view<_View, _Fn>::__iterator;
 
-  template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
-    requires __transform_view_constraints<_ViewType, _FunctionType>
-  friend class __transform_view_sentinel;
+  template<bool>
+  friend class transform_view<_View, _Fn>::__sentinel;
 
 public:
   _LIBCPP_HIDE_FROM_ABI
-  __transform_view_sentinel() = default;
+  __sentinel() = default;
 
   _LIBCPP_HIDE_FROM_ABI
-  constexpr explicit __transform_view_sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
+  constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
 
-  // Note: `__i` should always be `__transform_view_sentinel<false>`, but directly using
-  // `__transform_view_sentinel<false>` is ill-formed when `_Const` is false
+  // Note: `__i` should always be `__sentinel<false>`, but directly using
+  // `__sentinel<false>` is ill-formed when `_Const` is false
   // (see http://wg21.link/class.copy.ctor#5).
   _LIBCPP_HIDE_FROM_ABI
-  constexpr __transform_view_sentinel(__transform_view_sentinel<_View, _Fn, !_Const> __i)
+  constexpr __sentinel(__sentinel<!_Const> __i)
     requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
     : __end_(std::move(__i.__end_)) {}
 
@@ -413,7 +388,7 @@ class __transform_view_sentinel {
   template<bool _OtherConst>
     requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI
-  friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
+  friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
     return __x.__current_ == __y.__end_;
   }
 
@@ -421,7 +396,7 @@ class __transform_view_sentinel {
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI
   friend constexpr range_
diff erence_t<__maybe_const<_OtherConst, _View>>
-  operator-(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
+  operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
     return __x.__current_ - __y.__end_;
   }
 
@@ -429,7 +404,7 @@ class __transform_view_sentinel {
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
   _LIBCPP_HIDE_FROM_ABI
   friend constexpr range_
diff erence_t<__maybe_const<_OtherConst, _View>>
-  operator-(const __transform_view_sentinel& __x, const __iterator<_OtherConst>& __y) {
+  operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
     return __x.__end_ - __y.__current_;
   }
 };

diff  --git a/libcxx/test/std/ranges/iterator_robust_against_adl.compile.pass.cpp b/libcxx/test/std/ranges/iterator_robust_against_adl.compile.pass.cpp
new file mode 100644
index 0000000000000..5efd6c72a13db
--- /dev/null
+++ b/libcxx/test/std/ranges/iterator_robust_against_adl.compile.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// ADL call with nested iterators of views should not look up base's view's
+// namespace
+
+#include <ranges>
+#include <tuple>
+
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+#include <istream>
+#endif
+namespace adl {
+
+struct BaseView : std::ranges::view_base {
+  int* begin() const;
+  int* end() const;
+};
+
+struct TupleView : std::ranges::view_base {
+  std::tuple<int>* begin() const;
+  std::tuple<int>* end() const;
+};
+
+struct NestedView : std::ranges::view_base {
+  BaseView* begin() const;
+  BaseView* end() const;
+};
+
+struct Pred {
+  bool operator()(const auto&...) const;
+};
+
+struct Sentinel {
+  bool operator==(const auto&) const;
+};
+
+struct Value {
+  friend std::istream& operator>>(std::istream&, Value);
+};
+
+void adl_func(const auto&);
+
+} // namespace adl
+
+template <class View>
+concept CanFindADLFunc = requires(std::ranges::iterator_t<View> it) { adl_func(it); };
+
+static_assert(!CanFindADLFunc<std::ranges::elements_view<adl::TupleView, 0>>);
+static_assert(!CanFindADLFunc<std::ranges::filter_view<adl::BaseView, adl::Pred>>);
+static_assert(!CanFindADLFunc<std::ranges::iota_view<int, adl::Sentinel>>);
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+static_assert(!CanFindADLFunc<std::ranges::istream_view<adl::Value>>);
+#endif
+
+static_assert(!CanFindADLFunc<std::ranges::join_view<adl::NestedView>>);
+
+static_assert(!CanFindADLFunc<std::ranges::lazy_split_view<adl::BaseView, adl::BaseView>>);
+using InnerRange =
+    typename std::ranges::iterator_t<std::ranges::lazy_split_view<adl::BaseView, adl::BaseView>>::value_type;
+static_assert(!CanFindADLFunc<InnerRange >);
+
+static_assert(!CanFindADLFunc<std::ranges::split_view<adl::BaseView, adl::BaseView>>);
+static_assert(!CanFindADLFunc<std::ranges::transform_view<adl::BaseView, adl::Pred>>);
+
+#if TEST_STD_VER >= 23
+static_assert(!CanFindADLFunc<std::ranges::zip_view<adl::BaseView>>);
+#endif


        


More information about the libcxx-commits mailing list