diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h --- a/libcxx/include/__ranges/elements_view.h +++ b/libcxx/include/__ranges/elements_view.h @@ -49,12 +49,6 @@ namespace ranges { -template -class __elements_view_iterator; - -template -class __elements_view_sentinel; - template concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value; @@ -66,6 +60,13 @@ __has_tuple_element>, _Np> && __returnable_element, _Np> class elements_view : public view_interface> { +private: + template + class __iterator; + + template + class __sentinel; + public: _LIBCPP_HIDE_FROM_ABI elements_view() requires default_initializable<_View> @@ -130,12 +131,6 @@ } private: - template - using __iterator = __elements_view_iterator<_View, _Np, _Const>; - - template - using __sentinel = __elements_view_sentinel<_View, _Np, _Const>; - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); }; @@ -160,13 +155,18 @@ using iterator_category = decltype(__get_iterator_category()); }; -template -class __elements_view_iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { - template - friend class __elements_view_iterator; +template + requires view<_View> && __has_tuple_element, _Np> && + __has_tuple_element>, _Np> && + __returnable_element, _Np> +template +class elements_view<_View, _Np>::__iterator + : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { + template + friend class __iterator; - template - friend class __elements_view_sentinel; + template + friend class __sentinel; using _Base = __maybe_const<_Const, _View>; @@ -198,14 +198,13 @@ using value_type = remove_cvref_t>>; using difference_type = range_difference_t<_Base>; - _LIBCPP_HIDE_FROM_ABI __elements_view_iterator() + _LIBCPP_HIDE_FROM_ABI __iterator() requires default_initializable> = 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 __i) requires _Const && convertible_to, iterator_t<_Base>> : __current_(std::move(__i.__current_)) {} @@ -215,14 +214,14 @@ _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 @@ 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 @@ return temp; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator+=(difference_type __n) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) requires random_access_range<_Base> { __current_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator-=(difference_type __n) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) requires random_access_range<_Base> { __current_ -= __n; @@ -265,99 +264,91 @@ 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> { 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> { return __x.__current_ <=> __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator - operator+(const __elements_view_iterator& __x, difference_type __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_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+(difference_type __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_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, difference_type __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y) requires random_access_range<_Base> { - return __elements_view_iterator{__x} -= __y; + return __iterator{__x} -= __y; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type - operator-(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) requires sized_sentinel_for, iterator_t<_Base>> { return __x.__current_ - __y.__current_; } }; -template -class __elements_view_sentinel { +template + requires view<_View> && __has_tuple_element, _Np> && + __has_tuple_element>, _Np> && + __returnable_element, _Np> +template +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 - friend class __elements_view_sentinel; + template + friend class __sentinel; template - _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 __other) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__other.__end_)) {} @@ -365,22 +356,21 @@ template requires sentinel_for, 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 requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_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 requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_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 --- a/libcxx/include/__ranges/filter_view.h +++ b/libcxx/include/__ranges/filter_view.h @@ -46,15 +46,6 @@ #if _LIBCPP_STD_VER > 17 namespace ranges { - - template > _Pred> - requires view<_View> && is_object_v<_Pred> - class __filter_view_iterator; - - template > _Pred> - requires view<_View> && is_object_v<_Pred> - class __filter_view_sentinel; - template> _Pred> requires view<_View> && is_object_v<_Pred> class filter_view : public view_interface> { @@ -67,11 +58,8 @@ using _Cache = _If<_UseCache, __non_propagating_cache>, __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 @@ template> _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_iterator_tag, @@ -149,10 +135,10 @@ using difference_type = range_difference_t<_View>; _LIBCPP_HIDE_FROM_ABI - __filter_view_iterator() requires default_initializable> = default; + __iterator() requires default_initializable> = 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 @@ } _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 @@ _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> { 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> { @@ -224,17 +210,15 @@ template> _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 @@ 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 --- a/libcxx/include/__ranges/iota_view.h +++ b/libcxx/include/__ranges/iota_view.h @@ -83,14 +83,6 @@ { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>; }; - template - requires copyable<_Start> - struct __iota_view_iterator; - - template - requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> - struct __iota_view_sentinel; - template struct __iota_iterator_category {}; @@ -102,9 +94,211 @@ template requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> class iota_view : public view_interface> { + 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, forward_iterator_tag, + /*Else*/ input_iterator_tag>>>; + + using value_type = _Start; + using difference_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+=(difference_type __n) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { + if (__n >= difference_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-=(difference_type __n) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { + if (__n >= difference_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[](difference_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, difference_type __n) + requires __advanceable<_Start> + { + __i += __n; + return __i; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(difference_type __n, __iterator __i) + requires __advanceable<_Start> + { + return __i + __n; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator-(__iterator __i, difference_type __n) + requires __advanceable<_Start> + { + __i -= __n; + return __i; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start>) { + if constexpr (__signed_integer_like<_Start>) { + return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); + } + if (__y.__value_ > __x.__value_) { + return difference_type(-difference_type(__y.__value_ - __x.__value_)); + } + return difference_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_difference_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_difference_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 @@ template inline constexpr bool enable_borrowed_range> = true; - template - requires copyable<_Start> - struct __iota_view_iterator : public __iota_iterator_category<_Start> { - - template - 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, forward_iterator_tag, - /*Else*/ input_iterator_tag>>>; - - using value_type = _Start; - using difference_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+=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_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-=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_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[](difference_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, difference_type __n) - requires __advanceable<_Start> - { - __i += __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iota_view_iterator operator+(difference_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, difference_type __n) - requires __advanceable<_Start> - { - __i -= __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr difference_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 difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); - } - if (__y.__value_ > __x.__value_) { - return difference_type(-difference_type(__y.__value_ - __x.__value_)); - } - return difference_type(__x.__value_ - __y.__value_); - } - return __x.__value_ - __y.__value_; - } - }; - - template - requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> - struct __iota_view_sentinel { - - template - 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_difference_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_difference_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 --- a/libcxx/include/__ranges/istream_view.h +++ b/libcxx/include/__ranges/istream_view.h @@ -36,18 +36,10 @@ template concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; }; -template - requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits> -class __basic_istream_view_iterator; - template > requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits> class basic_istream_view : public view_interface> { - using __iterator = __basic_istream_view_iterator<_Val, _CharT, _Traits>; - - template - 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 @@ template 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 difference_type = ptrdiff_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 @@ _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 --- a/libcxx/include/__ranges/split_view.h +++ b/libcxx/include/__ranges/split_view.h @@ -42,12 +42,6 @@ namespace ranges { -template -struct __split_view_iterator; - -template -struct __split_view_sentinel; - template requires view<_View> && view<_Pattern> && indirectly_comparable, iterator_t<_Pattern>, ranges::equal_to> @@ -59,13 +53,13 @@ _Cache __cached_begin_ = _Cache(); template - friend struct __split_view_iterator; + friend struct __iterator; template - 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> __find_next(iterator_t<_View> __it) { auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_); @@ -120,16 +114,17 @@ template split_view(_Range&&, range_value_t<_Range>) -> split_view, single_view>>; -template -struct __split_view_iterator { +template + requires view<_View> && view<_Pattern> && + indirectly_comparable, 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> __next_ = subrange>(); bool __trailing_empty_ = false; - template - friend struct __split_view_sentinel; + friend struct __sentinel; public: using iterator_concept = forward_iterator_tag; @@ -137,9 +132,9 @@ using value_type = subrange>; using difference_type = range_difference_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> __next) : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {} @@ -147,7 +142,7 @@ _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 @@ 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 -struct __split_view_sentinel { +template + requires view<_View> && view<_Pattern> && + indirectly_comparable, 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 --- a/libcxx/include/__ranges/take_while_view.h +++ b/libcxx/include/__ranges/take_while_view.h @@ -53,17 +53,11 @@ concept __take_while_const_is_range = range && indirect_unary_predicate>; -template -class __take_while_view_sentinel; - template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> class take_while_view : public view_interface> { - template - friend class __take_while_view_sentinel; - - template - using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>; + template + class __sentinel; _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; @@ -114,37 +108,37 @@ template take_while_view(_Range&&, _Pred) -> take_while_view, _Pred>; -template -class __take_while_view_sentinel { +template + requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> +template +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 - friend class __take_while_view_sentinel; + friend class __sentinel; 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 __s) requires _Const && convertible_to, 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 requires sentinel_for, 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 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -57,31 +57,11 @@ regular_invocable<_Fn&, range_reference_t<_View>> && __can_reference>>; -template - requires __transform_view_constraints<_View, _Function> -class __transform_view_iterator; - -template - requires __transform_view_constraints<_View, _Function> -class __transform_view_sentinel; - template requires __transform_view_constraints<_View, _Fn> class transform_view : public view_interface> { - - template - using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>; - - template - using __sentinel = __transform_view_sentinel<_View, _Fn, _IsConst>; - - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; - - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template class __iterator; + template class __sentinel; _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_; _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); @@ -176,23 +156,22 @@ >; }; -template +template requires __transform_view_constraints<_View, _Fn> -class __transform_view_iterator +template +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 - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; + template + friend class transform_view<_View, _Fn>::__iterator; - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template + friend class transform_view<_View, _Fn>::__sentinel; public: iterator_t<_Base> __current_ = iterator_t<_Base>(); @@ -202,17 +181,17 @@ using difference_type = range_difference_t<_Base>; _LIBCPP_HIDE_FROM_ABI - __transform_view_iterator() requires default_initializable> = default; + __iterator() requires default_initializable> = 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`, but directly using - // `__transform_view_iterator` is ill-formed when `_Const` is false + // Note: `__i` should always be `__iterator`, but directly using + // `__iterator` 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 __i) requires _Const && convertible_to, iterator_t<_Base>> : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {} @@ -234,7 +213,7 @@ } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator++() { + constexpr __iterator& operator++() { ++__current_; return *this; } @@ -243,7 +222,7 @@ 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 @@ } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator--() + constexpr __iterator& operator--() requires bidirectional_range<_Base> { --__current_; @@ -260,7 +239,7 @@ } _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 @@ } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator+=(difference_type __n) + constexpr __iterator& operator+=(difference_type __n) requires random_access_range<_Base> { __current_ += __n; @@ -277,7 +256,7 @@ } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator-=(difference_type __n) + constexpr __iterator& operator-=(difference_type __n) requires random_access_range<_Base> { __current_ -= __n; @@ -293,77 +272,77 @@ } _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> { 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> { return __x.__current_ <=> __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr __transform_view_iterator operator+(__transform_view_iterator __i, difference_type __n) + friend constexpr __iterator operator+(__iterator __i, difference_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+(difference_type __n, __transform_view_iterator __i) + friend constexpr __iterator operator+(difference_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, difference_type __n) + friend constexpr __iterator operator-(__iterator __i, difference_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 difference_type operator-(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) requires sized_sentinel_for, 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) @@ -373,37 +352,33 @@ } }; -template +template requires __transform_view_constraints<_View, _Fn> -class __transform_view_sentinel { - using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>; +template +class transform_view<_View, _Fn>::__sentinel { + using _Parent = __maybe_const<_Const, transform_view>; using _Base = __maybe_const<_Const, _View>; - template - using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>; - sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; + template + friend class transform_view<_View, _Fn>::__iterator; - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template + 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`, but directly using - // `__transform_view_sentinel` is ill-formed when `_Const` is false + // Note: `__i` should always be `__sentinel`, but directly using + // `__sentinel` 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 __i) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__i.__end_)) {} @@ -413,7 +388,7 @@ template requires sentinel_for, 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 @@ requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_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 @@ requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_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 --- /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 +#include + +#include "test_macros.h" + +#ifndef TEST_HAS_NO_LOCALIZATION +#include +#endif +namespace adl { + +struct BaseView : std::ranges::view_base { + int* begin() const; + int* end() const; +}; + +struct TupleView : std::ranges::view_base { + std::tuple* begin() const; + std::tuple* 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 +concept CanFindADLFunc = requires(std::ranges::iterator_t it) { adl_func(it); }; + +static_assert(!CanFindADLFunc>); +static_assert(!CanFindADLFunc>); +static_assert(!CanFindADLFunc>); + +#ifndef TEST_HAS_NO_LOCALIZATION +static_assert(!CanFindADLFunc>); +#endif + +static_assert(!CanFindADLFunc>); + +static_assert(!CanFindADLFunc>); +using InnerRange = + typename std::ranges::iterator_t>::value_type; +static_assert(!CanFindADLFunc); + +static_assert(!CanFindADLFunc>); +static_assert(!CanFindADLFunc>); + +#if TEST_STD_VER >= 23 +static_assert(!CanFindADLFunc>); +#endif