[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
This commit is contained in:
Hui 2023-02-04 17:09:17 +00:00
parent 3b059cd25b
commit 4c2ad195f8
8 changed files with 448 additions and 465 deletions

View File

@ -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 @@ public:
}
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 @@ public:
using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;
using difference_type = range_difference_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 @@ public:
_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 @@ public:
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 @@ public:
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 @@ public:
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, 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>, 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 @@ public:
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_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 <bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, 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);
}
};

View File

@ -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 difference_type = range_difference_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_;
}
};

View File

@ -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 = __iota_view_iterator<_Start>;
using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>;
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 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_;
}
_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 @@ 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 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 <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_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 {

View File

@ -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 @@ private:
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 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 @@ public:
_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();
}

View File

@ -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 @@ private:
_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 @@ public:
using value_type = subrange<iterator_t<_View>>;
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<iterator_t<_View>> __next)
: __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
@ -147,7 +142,7 @@ public:
_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 @@ public:
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);
}
};

View File

@ -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 @@ public:
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);
}
};

View File

@ -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 @@ public:
using difference_type = range_difference_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 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
constexpr __transform_view_iterator& operator++() {
constexpr __iterator& operator++() {
++__current_;
return *this;
}
@ -243,7 +222,7 @@ public:
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 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
constexpr __transform_view_iterator& operator--()
constexpr __iterator& operator--()
requires bidirectional_range<_Base>
{
--__current_;
@ -260,7 +239,7 @@ public:
}
_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 @@ public:
}
_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 @@ public:
}
_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 @@ public:
}
_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, 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>, 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 @@ public:
}
};
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 @@ public:
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 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, 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 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, 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_;
}
};

View File

@ -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