[libcxx-commits] [libcxx] [libc++][ranges] P3059R2: Making user-defined constructors of view iterators/sentinels private (PR #193891)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 22 03:32:57 PDT 2026
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/193891
>From 68da1731c2ad8f5e98872b8df5e8dd5bfa646008 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 3 Apr 2026 08:43:06 +0300
Subject: [PATCH 01/28] [libc++][ranges] P3059R2: Making user-defined
constructors of view iterators/sentinels private
Implements https://wg21.link/P3059R2
Closes #189599
---
libcxx/include/__ranges/elements_view.h | 12 ++++++++----
libcxx/include/__ranges/filter_view.h | 20 ++++++++++++-------
libcxx/include/__ranges/iota_view.h | 15 ++++++++------
libcxx/include/__ranges/istream_view.h | 8 +++++---
libcxx/include/__ranges/join_view.h | 6 ++++--
libcxx/include/__ranges/lazy_split_view.h | 24 +++++++++++++----------
libcxx/include/__ranges/split_view.h | 18 ++++++++++-------
libcxx/include/__ranges/take_view.h | 6 ++++--
libcxx/include/__ranges/take_while_view.h | 8 +++++---
libcxx/include/__ranges/transform_view.h | 14 ++++++++-----
10 files changed, 82 insertions(+), 49 deletions(-)
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index 33c152bbd03b4..706744ae652e1 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -165,6 +165,8 @@ template <input_range _View, size_t _Np>
template <bool _Const>
class elements_view<_View, _Np>::__iterator
: public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
+ friend class elements_view<_View, _Np>;
+
template <bool>
friend class __iterator;
@@ -175,6 +177,8 @@ class elements_view<_View, _Np>::__iterator
iterator_t<_Base> __current_ = iterator_t<_Base>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
+
_LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) {
if constexpr (is_reference_v<range_reference_t<_Base>>) {
return std::get<_Np>(*__i);
@@ -205,8 +209,6 @@ class elements_view<_View, _Np>::__iterator
requires default_initializable<iterator_t<_Base>>
= default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
-
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __current_(std::move(__i.__current_)) {}
@@ -339,6 +341,10 @@ class elements_view<_View, _Np>::__sentinel {
using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
+
+ friend class elements_view<_View, _Np>;
+
template <bool>
friend class __sentinel;
@@ -350,8 +356,6 @@ class elements_view<_View, _Np>::__sentinel {
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
-
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__other.__end_)) {}
diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
index 7ec53dac4a84f..3004e830173f1 100644
--- a/libcxx/include/__ranges/filter_view.h
+++ b/libcxx/include/__ranges/filter_view.h
@@ -127,10 +127,16 @@ struct __filter_iterator_category<_View> {
template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
-public:
+private:
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
_LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
+ : __current_(std::move(__current)), __parent_(std::addressof(__parent)) {}
+
+ friend class filter_view<_View, _Pred>;
+
+public:
using iterator_concept =
_If<bidirectional_range<_View>,
bidirectional_iterator_tag,
@@ -145,9 +151,6 @@ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<
requires default_initializable<iterator_t<_View>>
= default;
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
- : __current_(std::move(__current)), __parent_(std::addressof(__parent)) {}
-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); }
@@ -211,13 +214,16 @@ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<
template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
class filter_view<_View, _Pred>::__sentinel {
-public:
+private:
sentinel_t<_View> __end_ = sentinel_t<_View>();
- _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
-
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(filter_view& __parent) : __end_(ranges::end(__parent.__base_)) {}
+ friend class filter_view<_View, _Pred>;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; }
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 38e0ccaf2849e..9d87138d29e23 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -110,6 +110,12 @@ template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_
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> {
+ private:
+ _Start __value_ = _Start();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
+
+ public:
friend class iota_view;
using iterator_concept =
@@ -124,14 +130,10 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
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)) {}
-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const
noexcept(is_nothrow_copy_constructible_v<_Start>) {
return __value_;
@@ -282,11 +284,12 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
private:
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
- public:
- _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
: __bound_sentinel_(std::move(__bound_sentinel)) {}
+ public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
return __x.__value_ == __y.__bound_sentinel_;
}
diff --git a/libcxx/include/__ranges/istream_view.h b/libcxx/include/__ranges/istream_view.h
index 7c64463108e1a..1bee6e69f2186 100644
--- a/libcxx/include/__ranges/istream_view.h
+++ b/libcxx/include/__ranges/istream_view.h
@@ -66,9 +66,6 @@ class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
using difference_type = ptrdiff_t;
using value_type = _Val;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
- : __parent_(std::addressof(__parent)) {}
-
__iterator(const __iterator&) = delete;
_LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
@@ -91,9 +88,14 @@ class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
private:
basic_istream_view<_Val, _CharT, _Traits>* __parent_;
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
+ : __parent_(std::addressof(__parent)) {}
+
_LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const {
return __parent_->__stream_;
}
+
+ friend class basic_istream_view<_Val, _CharT, _Traits>;
};
template <class _Val>
diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h
index f80b75c839d4a..4f3f8d1c1e5b4 100644
--- a/libcxx/include/__ranges/join_view.h
+++ b/libcxx/include/__ranges/join_view.h
@@ -160,11 +160,13 @@ struct join_view<_View>::__sentinel {
using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {}
+
+ friend class join_view<_View>;
+
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {}
-
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)) {}
diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h
index be2b86772fa0d..9c44d26faf1e7 100644
--- a/libcxx/include/__ranges/lazy_split_view.h
+++ b/libcxx/include/__ranges/lazy_split_view.h
@@ -143,6 +143,8 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
template <bool _Const>
struct __outer_iterator : __outer_iterator_category<__maybe_const<_Const, _View>> {
private:
+ friend class lazy_split_view<_View, _Pattern>;
+
template <bool>
friend struct __inner_iterator;
friend __outer_iterator<true>;
@@ -155,6 +157,14 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
_LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent();
bool __trailing_empty_ = false;
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(_Parent& __parent)
+ requires(!forward_range<_Base>)
+ : __parent_(std::addressof(__parent)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current)
+ requires forward_range<_Base>
+ : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto& __current() noexcept {
if constexpr (forward_range<_View>) {
return __current_;
@@ -196,14 +206,6 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
_LIBCPP_HIDE_FROM_ABI __outer_iterator() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(_Parent& __parent)
- requires(!forward_range<_Base>)
- : __parent_(std::addressof(__parent)) {}
-
- _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current)
- requires forward_range<_Base>
- : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
-
_LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(__outer_iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
@@ -286,12 +288,16 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
template <bool _Const>
struct __inner_iterator : __inner_iterator_category<__maybe_const<_Const, _View>> {
private:
+ friend class lazy_split_view<_View, _Pattern>;
+
using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
// Workaround for a GCC issue.
static constexpr bool _OuterConst = _Const;
__outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>();
bool __incremented_ = false;
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) : __i_(std::move(__i)) {}
+
// Note: these private functions are necessary because GCC doesn't allow calls to private members of `__i_` from
// free functions that are friends of `inner-iterator`.
@@ -342,8 +348,6 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
_LIBCPP_HIDE_FROM_ABI __inner_iterator() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) : __i_(std::move(__i)) {}
-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept {
return __i_.__current();
}
diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h
index 10148e0e64764..7295e33a282f0 100644
--- a/libcxx/include/__ranges/split_view.h
+++ b/libcxx/include/__ranges/split_view.h
@@ -127,6 +127,12 @@ struct split_view<_View, _Pattern>::__iterator {
_LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
bool __trailing_empty_ = false;
+ _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)) {}
+
+ friend class split_view<_View, _Pattern>;
+
friend struct __sentinel;
public:
@@ -137,10 +143,6 @@ struct split_view<_View, _Pattern>::__iterator {
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
- _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)) {}
-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() const { return __cur_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
@@ -179,16 +181,18 @@ struct split_view<_View, _Pattern>::__sentinel {
private:
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent)
+ : __end_(ranges::end(__parent.__base_)) {}
+
_LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) {
return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
}
+ friend class split_view<_View, _Pattern>;
+
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _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 __iterator& __x, const __sentinel& __y) {
return __equals(__x, __y);
}
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 999f686537f2c..ee62d49f71d8b 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -165,14 +165,16 @@ class take_view<_View>::__sentinel {
using _Iter _LIBCPP_NODEBUG = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
+
+ friend class take_view<_View>;
+
template <bool>
friend class take_view<_View>::__sentinel;
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
-
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)) {}
diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h
index 0aee306807c8b..e77b79665d1f6 100644
--- a/libcxx/include/__ranges/take_while_view.h
+++ b/libcxx/include/__ranges/take_while_view.h
@@ -108,14 +108,16 @@ class take_while_view<_View, _Pred>::__sentinel {
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
const _Pred* __pred_ = nullptr;
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
+ : __end_(std::move(__end)), __pred_(__pred) {}
+
+ friend class take_while_view<_View, _Pred>;
+
friend class __sentinel<!_Const>;
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _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 __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {}
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 06ace86bbfafa..807f1cf19a0ac 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -192,6 +192,11 @@ class transform_view<_View, _Fn>::__iterator
_Parent* __parent_ = nullptr;
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
+ : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
+
+ friend class transform_view<_View, _Fn>;
+
template <bool>
friend class transform_view<_View, _Fn>::__iterator;
@@ -209,9 +214,6 @@ class transform_view<_View, _Fn>::__iterator
requires default_initializable<iterator_t<_Base>>
= default;
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
- : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
-
// 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).
@@ -354,6 +356,10 @@ class transform_view<_View, _Fn>::__sentinel {
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
+
+ friend class transform_view<_View, _Fn>;
+
template <bool>
friend class transform_view<_View, _Fn>::__iterator;
@@ -363,8 +369,6 @@ class transform_view<_View, _Fn>::__sentinel {
public:
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
-
// 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).
>From c4d11be4adc7c07fd52f608bea12da28e8221371 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 6 Apr 2026 00:45:01 +0300
Subject: [PATCH 02/28] Tests: `split_view`
---
.../range.split/iterator/base.pass.cpp | 28 +++++++++++++------
.../range.split/iterator/ctor.base.pass.cpp | 4 +--
.../range.split/iterator/deref.pass.cpp | 28 ++++++++++++-------
.../range.split/sentinel/ctor.parent.pass.cpp | 5 +---
4 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
index 325189a0e521e..66c2914ba1919 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
@@ -16,9 +16,20 @@
#include "../types.h"
struct Iter : ForwardIterBase<Iter> {
- int i;
+ int i = 0;
constexpr Iter() = default;
constexpr Iter(int ii) : i(ii) {}
+ constexpr int operator*() const { return i; }
+ constexpr Iter& operator++() {
+ ++i;
+ return *this;
+ }
+ constexpr Iter operator++(int) {
+ Iter tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ friend constexpr bool operator==(const Iter& x, const Iter& y) { return x.i == y.i; }
};
constexpr bool test() {
@@ -26,34 +37,33 @@ constexpr bool test() {
using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
using SplitIter = std::ranges::iterator_t<SplitView>;
+ SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}},
+ std::ranges::subrange<Iter>{Iter{8}, Iter{9}}};
+
// const &
{
- SplitView sv;
- const SplitIter it{sv, Iter{5}, {}};
+ const SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = it.base();
assert(base.i == 5);
}
// &
{
- SplitView sv;
- SplitIter it{sv, Iter{5}, {}};
+ SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = it.base();
assert(base.i == 5);
}
// &&
{
- SplitView sv;
- SplitIter it{sv, Iter{5}, {}};
+ SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = std::move(it).base();
assert(base.i == 5);
}
// const &&
{
- SplitView sv;
- const SplitIter it{sv, Iter{5}, {}};
+ const SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = std::move(it).base();
assert(base.i == 5);
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
index 20b3c19611bd0..823e22e117f77 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
@@ -8,7 +8,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
-// constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);
+// constexpr iterator begin();
#include <cassert>
#include <ranges>
@@ -35,7 +35,7 @@ constexpr bool test() {
using SplitIter = std::ranges::iterator_t<SplitView>;
SplitView sv{TracedMoveView{}, TracedMoveView{}};
- SplitIter iter = {sv, sv.base().begin(), std::ranges::subrange<TracedMoveIter>{sv.base().begin(), sv.base().end()}};
+ SplitIter iter = sv.begin();
assert(iter.base().moved);
auto subRange = *iter;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
index 721a1cc0da3d4..be7aca854f640 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
@@ -17,24 +17,32 @@
#include "../types.h"
struct Iter : ForwardIterBase<Iter> {
- int i;
+ int i = 0;
constexpr Iter() = default;
constexpr Iter(int ii) : i(ii) {}
+ constexpr int operator*() const { return i; }
+ constexpr Iter& operator++() {
+ ++i;
+ return *this;
+ }
+ constexpr Iter operator++(int) {
+ Iter tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ friend constexpr bool operator==(const Iter& x, const Iter& y) { return x.i == y.i; }
};
constexpr bool test() {
using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
using SplitIter = std::ranges::iterator_t<SplitView>;
- {
- SplitView sv;
- Iter current{5};
- std::ranges::subrange next{Iter{6}, Iter{7}};
- const SplitIter it{sv, current, next};
- std::same_as<std::ranges::subrange<Iter>> decltype(auto) value = *it;
- assert(value.begin().i == 5);
- assert(value.end().i == 6);
- }
+ SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}},
+ std::ranges::subrange<Iter>{Iter{7}, Iter{8}}};
+ const SplitIter it = sv.begin();
+ std::same_as<std::ranges::subrange<Iter>> decltype(auto) value = *it;
+ assert(value.begin().i == 5);
+ assert(value.end().i == 7);
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
index c89b1ee2bdfce..6e1ba912a201b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
@@ -21,9 +21,6 @@ using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
using SplitSent = std::ranges::sentinel_t<SplitView>;
-static_assert(std::is_constructible_v<SplitSent, SplitView&>);
-static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
-
constexpr bool test() {
{
int buffer[] = {0, 1, 2};
@@ -31,7 +28,7 @@ constexpr bool test() {
SplitView sv(input, -1);
auto it = sv.begin();
- SplitSent sent(sv);
+ auto sent = sv.end();
assert(sent != it);
++it;
>From 781eaa5dbef3351d87574cf432106a2a7d7c9a38 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 6 Apr 2026 00:48:57 +0300
Subject: [PATCH 03/28] Tests: `take_view`
---
.../range.take/range.take.sentinel/ctor.pass.cpp | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp
index 61d33760c71d7..3710be563c15b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.pass.cpp
@@ -9,7 +9,6 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// sentinel() = default;
-// constexpr explicit sentinel(sentinel_t<Base> end);
// constexpr sentinel(sentinel<!Const> s)
// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
@@ -49,18 +48,6 @@ constexpr bool test() {
assert(std::as_const(tv).begin() + 4 == cs);
}
- {
- // Test the constructor from "base-sentinel" to "sentinel".
- using TakeView = std::ranges::take_view<MoveOnlyView>;
- using Sentinel = std::ranges::sentinel_t<TakeView>;
- sentinel_wrapper<int*> sw1 = MoveOnlyView(buffer).end();
- static_assert(std::is_constructible_v<Sentinel, sentinel_wrapper<int*>>);
- static_assert(!std::is_convertible_v<sentinel_wrapper<int*>, Sentinel>);
- auto s = Sentinel(sw1);
- std::same_as<sentinel_wrapper<int*>> auto sw2 = s.base();
- assert(base(sw2) == base(sw1));
- }
-
return true;
}
>From 195931a66e133699188de65ed5b8ee7f9aef2fe7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 12:41:47 +0300
Subject: [PATCH 04/28] Tests: `take_while_view`
---
.../sentinel/ctor.base.pass.cpp | 86 -------------------
.../sentinel/ctor.convert.pass.cpp | 43 +++++++---
2 files changed, 31 insertions(+), 98 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp
deleted file mode 100644
index b952534d1c966..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
-
-#include <cassert>
-#include <ranges>
-#include <utility>
-
-#include "../types.h"
-
-struct Sent {
- int i;
-
- friend constexpr bool operator==(int* iter, const Sent& s) { return s.i > *iter; }
-};
-
-struct Range : std::ranges::view_base {
- int* begin() const;
- Sent end();
-};
-
-struct Pred {
- bool operator()(int i) const;
-};
-
-// Test explicit
-template <class T>
-void conversion_test(T);
-
-template <class T, class... Args>
-concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
-static_assert(ImplicitlyConstructible<int, int>);
-
-static_assert(std::is_constructible_v<std::ranges::sentinel_t<std::ranges::take_while_view<Range, Pred>>,
- std::ranges::sentinel_t<Range>,
- const Pred*>);
-static_assert(!ImplicitlyConstructible<std::ranges::sentinel_t<std::ranges::take_while_view<Range, Pred>>,
- std::ranges::sentinel_t<Range>,
- const Pred*>);
-
-constexpr bool test() {
- // base is init correctly
- {
- using R = std::ranges::take_while_view<Range, bool (*)(int)>;
- using Sentinel = std::ranges::sentinel_t<R>;
-
- Sentinel s1(Sent{5}, nullptr);
- assert(s1.base().i == 5);
- }
-
- // pred is init correctly
- {
- bool called = false;
- auto pred = [&](int) {
- called = true;
- return false;
- };
-
- using R = std::ranges::take_while_view<Range, decltype(pred)>;
- using Sentinel = std::ranges::sentinel_t<R>;
-
- int i = 10;
- int* iter = &i;
- Sentinel s(Sent{0}, &pred);
-
- bool b = iter == s;
- assert(called);
- assert(b);
- }
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
index 865a3d45710fb..0fffe9b508816 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
@@ -70,34 +70,48 @@ static_assert(!std::is_constructible_v<
constexpr bool test() {
// base is init correctly
{
- using R = std::ranges::take_while_view<Range, bool (*)(int)>;
+ struct TestRng : std::ranges::view_base {
+ constexpr int* begin() const { return nullptr; }
+ constexpr Sent end() { return Sent{5}; }
+ constexpr ConstSent end() const { return ConstSent{5}; }
+ };
+
+ using R = std::ranges::take_while_view<TestRng, bool (*)(int)>;
using Sentinel = std::ranges::sentinel_t<R>;
using ConstSentinel = std::ranges::sentinel_t<const R>;
static_assert(!std::same_as<Sentinel, ConstSentinel>);
- Sentinel s1(Sent{5}, nullptr);
+ R r{TestRng{}, nullptr};
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
assert(s2.base().i == 5);
}
// pred is init correctly
{
+ struct TestRng : std::ranges::view_base {
+ constexpr int* begin() const { return nullptr; }
+ constexpr Sent end() { return Sent{0}; }
+ constexpr ConstSent end() const { return ConstSent{0}; }
+ };
+
bool called = false;
auto pred = [&](int) {
called = true;
return false;
};
- using R = std::ranges::take_while_view<Range, decltype(pred)>;
+ using R = std::ranges::take_while_view<TestRng, decltype(pred)>;
using Sentinel = std::ranges::sentinel_t<R>;
using ConstSentinel = std::ranges::sentinel_t<const R>;
static_assert(!std::same_as<Sentinel, ConstSentinel>);
- int i = 10;
- int* iter = &i;
- Sentinel s1(Sent{0}, &pred);
+ R r{TestRng{}, pred};
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
+ int i = 10;
+ int* iter = &i;
[[maybe_unused]] bool b = iter == s2;
assert(called);
}
@@ -111,20 +125,25 @@ constexpr bool test() {
constexpr bool operator==(int* iter) const { return i > *iter; }
};
+ struct TestPred {
+ constexpr bool operator()(int) const { return false; }
+ };
+
struct Rng : std::ranges::view_base {
- int* begin() const;
- Sent end();
- MoveOnlyConvert end() const;
+ constexpr int* begin() const { return nullptr; }
+ constexpr Sent end() { return Sent{0}; }
+ constexpr MoveOnlyConvert end() const { return MoveOnlyConvert(Sent{0}); }
};
- using R = std::ranges::take_while_view<Rng, Pred>;
+ using R = std::ranges::take_while_view<Rng, TestPred>;
using Sentinel = std::ranges::sentinel_t<R>;
using ConstSentinel = std::ranges::sentinel_t<const R>;
static_assert(!std::same_as<Sentinel, ConstSentinel>);
- Sentinel s1(Sent{5}, nullptr);
+ R r{Rng{}, TestPred{}};
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
- assert(s2.base().i == 5);
+ assert(s2.base().i == 0);
}
return true;
>From 26cf1daff36cae1d3e5f5476f7faba71cb019296 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 12:58:00 +0300
Subject: [PATCH 05/28] Tests: `filter_view`
---
.../range.filter/iterator/arrow.pass.cpp | 3 +-
.../range.filter/iterator/base.pass.cpp | 4 +-
.../iterator/ctor.parent_iter.pass.cpp | 51 ----------------
.../range.filter/iterator/deref.pass.cpp | 3 +-
.../sentinel/ctor.parent.pass.cpp | 60 -------------------
5 files changed, 6 insertions(+), 115 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
index 8a12b1694ca2f..46d59c3de1d7d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
@@ -87,7 +87,8 @@ constexpr void test() {
for (std::ptrdiff_t n = 0; n != 5; ++n) {
FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{});
- FilterIterator const iter(view, Iter(array.data() + n));
+ FilterIterator iter = view.begin();
+ for (std::ptrdiff_t i = 0; i < n; ++i) ++iter;
std::same_as<Iter> decltype(auto) result = iter.operator->();
assert(base(result) == array.data() + n);
assert(iter->x == n);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp
index 813cd892c64e6..9f193ddbc1a2d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp
@@ -37,7 +37,7 @@ constexpr void test() {
// Test the const& version
{
- FilterIterator const iter(view, Iter(array.data()));
+ FilterIterator const iter = view.begin();
Iter const& result = iter.base();
ASSERT_SAME_TYPE(Iter const&, decltype(iter.base()));
ASSERT_NOEXCEPT(iter.base());
@@ -46,7 +46,7 @@ constexpr void test() {
// Test the && version
{
- FilterIterator iter(view, Iter(array.data()));
+ FilterIterator iter = view.begin();
Iter result = std::move(iter).base();
ASSERT_SAME_TYPE(Iter, decltype(std::move(iter).base()));
assert(base(result) == array.data());
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp
deleted file mode 100644
index 761ef2d8ee493..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr std::ranges::filter_view::<iterator>(filter_view&, iterator_t<V>);
-
-#include <ranges>
-
-#include <array>
-#include <cassert>
-#include <utility>
-#include "test_iterators.h"
-#include "../types.h"
-
-template <class Iter, class Sent = sentinel_wrapper<Iter>>
-constexpr void test() {
- using View = minimal_view<Iter, Sent>;
- using FilterView = std::ranges::filter_view<View, AlwaysTrue>;
- using FilterIterator = std::ranges::iterator_t<FilterView>;
-
- std::array<int, 10> array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- View view(Iter(array.data()), Sent(Iter(array.data() + array.size())));
- Iter iter = view.begin();
-
- FilterView filter_view(std::move(view), AlwaysTrue{});
- FilterIterator filter_iter(filter_view, std::move(iter));
- assert(base(filter_iter.base()) == array.data());
-}
-
-constexpr bool tests() {
- test<cpp17_input_iterator<int*>>();
- test<cpp20_input_iterator<int*>>();
- test<forward_iterator<int*>>();
- test<bidirectional_iterator<int*>>();
- test<random_access_iterator<int*>>();
- test<contiguous_iterator<int*>>();
- test<int*>();
- return true;
-}
-
-int main(int, char**) {
- tests();
- static_assert(tests());
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
index f4f4982bb9d5d..e794ff133dcb0 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
@@ -36,7 +36,8 @@ constexpr void test() {
FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{});
for (std::size_t n = 0; n != array.size(); ++n) {
- FilterIterator const iter(view, Iter(array.data() + n));
+ FilterIterator iter = view.begin();
+ for (std::size_t i = 0; i < n; ++i) ++iter;
ValueType& result = *iter;
ASSERT_SAME_TYPE(ValueType&, decltype(*iter));
assert(&result == array.data() + n);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp
deleted file mode 100644
index 9896bf80c31e1..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit sentinel(filter_view&);
-
-#include <ranges>
-
-#include <array>
-#include <cassert>
-#include <type_traits>
-#include <utility>
-#include "test_iterators.h"
-#include "../types.h"
-
-template <class Iter, class Sent = sentinel_wrapper<Iter>>
-constexpr void test() {
- using View = minimal_view<Iter, Sent>;
- using FilterView = std::ranges::filter_view<View, AlwaysTrue>;
- using FilterSentinel = std::ranges::sentinel_t<FilterView>;
-
- auto make_filter_view = [](auto begin, auto end, auto pred) {
- View view{Iter(begin), Sent(Iter(end))};
- return FilterView(std::move(view), pred);
- };
-
- std::array<int, 5> array{0, 1, 2, 3, 4};
- FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{});
-
- FilterSentinel sent(view);
- assert(base(base(sent.base())) == base(base(view.end().base())));
-
- static_assert(!std::is_constructible_v<FilterSentinel, FilterView const&>);
- static_assert(!std::is_constructible_v<FilterSentinel, FilterView>);
- static_assert( std::is_constructible_v<FilterSentinel, FilterView&> &&
- !std::is_convertible_v<FilterView&, FilterSentinel>);
-}
-
-constexpr bool tests() {
- test<cpp17_input_iterator<int*>>();
- test<cpp20_input_iterator<int*>>();
- test<forward_iterator<int*>>();
- test<bidirectional_iterator<int*>>();
- test<random_access_iterator<int*>>();
- test<contiguous_iterator<int*>>();
- test<int*>();
- return true;
-}
-
-int main(int, char**) {
- tests();
- static_assert(tests());
- return 0;
-}
>From 11b933048f6a2b6279d2ff8b643ce845975d5efe Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 13:10:28 +0300
Subject: [PATCH 06/28] Tests: `lazy_split_view`
---
.../ctor.outer_iterator.pass.cpp | 43 -------------------
.../ctor.parent.pass.cpp | 39 -----------------
.../ctor.parent_base.pass.cpp | 36 ----------------
3 files changed, 118 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp
deleted file mode 100644
index 4981510be52d6..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.pass.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit inner-iterator::inner-iterator(outer-iterator<Const> i);
-
-#include <ranges>
-
-#include "../types.h"
-
-static_assert(!std::is_constructible_v<InnerIterNonConst, OuterIterConst>);
-
-template <class Inner, class Outer>
-constexpr void test_impl() {
- [[maybe_unused]] Inner i(Outer{});
- // Verify that the constructor is `explicit`.
- static_assert(!std::is_convertible_v<Outer, Inner>);
-}
-
-constexpr bool test() {
- test_impl<InnerIterForward, OuterIterForward>();
- test_impl<InnerIterInput, OuterIterInput>();
-// Is only constructible if both the outer and the inner iterators have the same constness.
- test_impl<InnerIterConst, OuterIterConst>();
-// Note: this works because of an implicit conversion (`OuterIterNonConst` is converted to `OuterIterConst`).
- test_impl<InnerIterConst, OuterIterNonConst>();
- test_impl<InnerIterNonConst, OuterIterNonConst>();
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp
deleted file mode 100644
index aacf6eabc290a..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.pass.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// explicit std::ranges::lazy_split_view::outer-iterator::outer-iterator(Parent& parent)
-// requires (!forward_range<Base>)
-
-#include <ranges>
-
-#include <type_traits>
-#include <utility>
-#include "../types.h"
-
-// Verify that the constructor is `explicit`.
-static_assert(!std::is_convertible_v<SplitViewInput&, OuterIterInput>);
-
-static_assert( std::ranges::forward_range<SplitViewForward>);
-static_assert(!std::is_constructible_v<OuterIterForward, SplitViewForward&>);
-
-constexpr bool test() {
- InputView input;
- SplitViewInput v(input, ForwardTinyView());
- [[maybe_unused]] OuterIterInput i(v);
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp
deleted file mode 100644
index 9fc0ce3748b1f..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent_base.pass.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr outer-iterator(Parent& parent, iterator_t<Base> current);
-// requires forward_range<Base>
-
-#include <ranges>
-
-#include <type_traits>
-#include <utility>
-#include "../types.h"
-
-static_assert(!std::ranges::forward_range<SplitViewInput>);
-static_assert(!std::is_constructible_v<OuterIterInput, SplitViewInput&, std::ranges::iterator_t<InputView>>);
-
-constexpr bool test() {
- ForwardView input("abc");
- SplitViewForward v(std::move(input), " ");
- [[maybe_unused]] OuterIterForward i(v, input.begin());
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
>From 74f795f5f559b72803edd152d2f60b772dd697d8 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 13:15:21 +0300
Subject: [PATCH 07/28] Tests: `join_view`
---
.../range.join.sentinel/ctor.parent.pass.cpp | 43 -------------------
1 file changed, 43 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
deleted file mode 100644
index 1ac68277338fe..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.pass.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit sentinel(Parent& parent);
-
-#include <cassert>
-#include <ranges>
-
-#include "test_macros.h"
-#include "../types.h"
-
-constexpr bool test() {
- int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
-
- CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]), CopyableChild(buffer[3])};
- CopyableParent parent{children};
- std::ranges::join_view jv(parent);
- std::ranges::sentinel_t<decltype(jv)> sent(jv);
- assert(sent == std::ranges::next(jv.begin(), 16));
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- {
- // Test explicitness.
- using Parent = std::ranges::join_view<ParentView<ChildView>>;
- static_assert( std::is_constructible_v<std::ranges::sentinel_t<Parent>, Parent&>);
- static_assert(!std::is_convertible_v<std::ranges::sentinel_t<Parent>, Parent&>);
- }
-
- return 0;
-}
>From 3f679ac8813a96d8179f8b72000153c3be0c1f50 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 13:47:11 +0300
Subject: [PATCH 08/28] Tests: `istream_view`
---
.../range.istream.view/ctor.pass.cpp | 5 +-
.../range.istream.view/iterator/ctor.pass.cpp | 58 -------------------
.../iterator/deref.pass.cpp | 10 ----
3 files changed, 2 insertions(+), 71 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
index ff60fbff1d73b..beeeea4c1bbe1 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
@@ -39,10 +39,9 @@ void test() {
// LWG 3568. basic_istream_view needs to initialize value_
{
- auto iss = make_string_stream<CharT>("123");
+ auto iss = make_string_stream<CharT>("");
std::ranges::basic_istream_view<int, CharT> isv{iss};
- using Iter = std::ranges::iterator_t<decltype(isv)>;
- Iter iter{isv};
+ auto iter = isv.begin();
assert(*iter == 0);
}
}
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp
deleted file mode 100644
index e180d12924084..0000000000000
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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: no-localization
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// constexpr explicit iterator(basic_istream_view& parent) noexcept;
-
-#include <cassert>
-#include <ranges>
-#include <sstream>
-#include <type_traits>
-
-#include "test_macros.h"
-#include "../utils.h"
-
-// test that the constructor is explicit
-template <class CharT>
-using IstreamView = std::ranges::basic_istream_view<int, CharT>;
-template <class CharT>
-using Iter = std::ranges::iterator_t<IstreamView<CharT>>;
-
-static_assert(std::constructible_from<Iter<char>, IstreamView<char>&>);
-static_assert(!std::convertible_to<IstreamView<char>&, Iter<char>>);
-
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::constructible_from<Iter<wchar_t>, IstreamView<wchar_t>&>);
-static_assert(!std::convertible_to<IstreamView<wchar_t>&, Iter<wchar_t>>);
-#endif
-
-// test that the constructor is noexcept
-static_assert(std::is_nothrow_constructible_v<Iter<char>, IstreamView<char>&>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_nothrow_constructible_v<Iter<wchar_t>, IstreamView<wchar_t>&>);
-#endif
-
-template <class CharT>
-void test() {
- auto iss = make_string_stream<CharT>("123");
- std::ranges::basic_istream_view<int, CharT> isv{iss};
- Iter<CharT> it{isv};
- ++it;
- assert(*it == 123);
-}
-
-int main(int, char**) {
- test<char>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test<wchar_t>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
index 1cf05f0ac4cbe..d010ee06dbf51 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
@@ -29,16 +29,6 @@ void test() {
assert(v1 == 1);
}
- // operator* should return the same reference to the value stored in the view
- {
- auto iss = make_string_stream<CharT>("1 2 345 ");
- std::ranges::basic_istream_view<int, CharT> isv{iss};
- using Iter = std::ranges::iterator_t<decltype(isv)>;
-
- Iter it1{isv};
- Iter it2{isv};
- assert(&*it1 == &*it2);
- }
}
int main(int, char**) {
>From 1bd7d694c3339a6b4e16a60a00817dc2130aa312 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 9 Apr 2026 14:00:32 +0300
Subject: [PATCH 09/28] Tests: `iota_view`
---
.../iterator/ctor.value.pass.cpp | 45 ------------------
.../sentinel/ctor.value.pass.cpp | 47 -------------------
2 files changed, 92 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp
deleted file mode 100644
index a84cb91f7e9b3..0000000000000
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit iterator(W value);
-
-#include <cassert>
-#include <ranges>
-#include <type_traits>
-
-#include "test_macros.h"
-#include "../types.h"
-
-constexpr bool test() {
- {
- using Iter = std::ranges::iterator_t<std::ranges::iota_view<int>>;
- auto iter = Iter(42);
- assert(*iter == 42);
- }
- {
- using Iter = std::ranges::iterator_t<std::ranges::iota_view<SomeInt>>;
- auto iter = Iter(SomeInt(42));
- assert(*iter == SomeInt(42));
- }
- {
- using Iter = std::ranges::iterator_t<std::ranges::iota_view<SomeInt>>;
- static_assert(!std::is_convertible_v<Iter, SomeInt>);
- static_assert( std::is_constructible_v<Iter, SomeInt>);
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp
deleted file mode 100644
index a56369b046dc1..0000000000000
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit sentinel(Bound bound);
-
-#include <cassert>
-#include <ranges>
-#include <type_traits>
-
-#include "test_macros.h"
-#include "../types.h"
-
-constexpr bool test() {
- {
- using Sent = std::ranges::sentinel_t<std::ranges::iota_view<int, IntSentinelWith<int>>>;
- using Iter = std::ranges::iterator_t<std::ranges::iota_view<int, IntSentinelWith<int>>>;
- auto sent = Sent(IntSentinelWith<int>(42));
- assert(sent == Iter(42));
- }
- {
- using Sent = std::ranges::sentinel_t<std::ranges::iota_view<SomeInt, IntSentinelWith<SomeInt>>>;
- using Iter = std::ranges::iterator_t<std::ranges::iota_view<SomeInt, IntSentinelWith<SomeInt>>>;
- auto sent = Sent(IntSentinelWith<SomeInt>(SomeInt(42)));
- assert(sent == Iter(SomeInt(42)));
- }
- {
- using Sent = std::ranges::sentinel_t<std::ranges::iota_view<SomeInt, IntSentinelWith<SomeInt>>>;
- static_assert(!std::is_convertible_v<Sent, IntSentinelWith<SomeInt>>);
- static_assert( std::is_constructible_v<Sent, IntSentinelWith<SomeInt>>);
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
>From 5a43b67d99477e25e09d5e2bf471de20bd21ad64 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 11 Apr 2026 14:45:00 +0300
Subject: [PATCH 10/28] Tests: `elements_view`
---
.../range.elements/iterator/base.pass.cpp | 12 +++--
.../iterator/ctor.base.pass.cpp | 54 -------------------
.../iterator/ctor.other.pass.cpp | 8 +--
.../range.elements/sentinel/base.pass.cpp | 7 +--
.../sentinel/ctor.base.pass.cpp | 52 ------------------
.../sentinel/ctor.convert.pass.cpp | 9 ++--
6 files changed, 20 insertions(+), 122 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
index a77e98f845a06..425c13fea707e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
@@ -39,7 +39,7 @@ constexpr bool test() {
// const &
{
- const ElementsIter it{&t};
+ const ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = it.base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
@@ -47,7 +47,7 @@ constexpr bool test() {
// &
{
- ElementsIter it{&t};
+ ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = it.base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
@@ -55,7 +55,7 @@ constexpr bool test() {
// &&
{
- ElementsIter it{&t};
+ ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>*>);
assert(base == &t);
@@ -63,7 +63,7 @@ constexpr bool test() {
// const &&
{
- const ElementsIter it{&t};
+ const ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
@@ -81,7 +81,9 @@ constexpr bool test() {
using MoveOnlyElemIter =
std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>>;
- MoveOnlyElemIter it{MoveOnlyIter{{}, MoveOnly{5}}};
+ auto it = std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>{
+ std::ranges::subrange{MoveOnlyIter{{}, MoveOnly{5}}, Sent{}}}
+ .begin();
decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), MoveOnlyIter>);
assert(base.mo.get() == 5);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp
deleted file mode 100644
index 5a280d294aecc..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.pass.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit iterator(iterator_t<Base> current);
-
-#include <cassert>
-#include <ranges>
-#include <tuple>
-
-#include "../types.h"
-
-// Test explicit
-using BaseIter = std::tuple<int>*;
-using ElementsIter = std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<BaseIter, BaseIter>, 0>>;
-
-static_assert(std::is_constructible_v<ElementsIter, BaseIter>);
-static_assert(!std::is_convertible_v<BaseIter, ElementsIter>);
-
-struct TracedMoveIter : IterBase<TracedMoveIter>{
- bool moved = false;
-
- constexpr TracedMoveIter() = default;
- constexpr TracedMoveIter(const TracedMoveIter&) = default;
- constexpr TracedMoveIter(TracedMoveIter&&) : moved{true} {}
- constexpr TracedMoveIter& operator=(TracedMoveIter&&) = default;
- constexpr TracedMoveIter& operator=(const TracedMoveIter&) = default;
-};
-
-struct TracedMoveView : std::ranges::view_base {
- TracedMoveIter begin() const;
- TracedMoveIter end() const;
-};
-
-constexpr bool test() {
- using Iter = std::ranges::iterator_t<std::ranges::elements_view<TracedMoveView, 0>>;
- Iter iter{TracedMoveIter{}};
- assert(iter.base().moved);
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
index 4c94cd5edf62e..d1b8ea73d635d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
@@ -57,10 +57,10 @@ static_assert(!std::is_constructible_v<ConstElemIter<NonConvertibleView>, ElemIt
static_assert(!std::is_constructible_v<ElemIter<NonConvertibleView>, ConstElemIter<NonConvertibleView>>);
constexpr bool test() {
- ElemIter<ConvertibleView> iter{ConvertibleIter<false>{5}};
- ConstElemIter<ConvertibleView> constIter = iter; // implicit
- assert(constIter.base().movedFromOtherConst);
- assert(constIter.base().i == 5);
+ // auto iter = std::ranges::elements_view<ConvertibleView, 0>{}.begin();
+ // ConstElemIter<ConvertibleView> constIter = iter; // implicit
+ // assert(constIter.base().movedFromOtherConst);
+ // assert(constIter.base().i == 5);
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
index d4d0156fdb5be..a11d16817f030 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
@@ -17,7 +17,7 @@
#include <utility>
struct Sent {
- int i;
+ int i = 5;
friend constexpr bool operator==(std::tuple<int>*, const Sent&) { return true; }
};
@@ -27,7 +27,8 @@ constexpr bool test() {
using EleRange = std::ranges::elements_view<BaseRange, 0>;
using EleSent = std::ranges::sentinel_t<EleRange>;
- const EleSent st{Sent{5}};
+ const EleRange ev;
+ const EleSent st = ev.end();
std::same_as<Sent> decltype(auto) base = st.base();
assert(base.i == 5);
@@ -36,6 +37,6 @@ constexpr bool test() {
int main(int, char**) {
test();
- static_assert(test());
+ // static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp
deleted file mode 100644
index 13fef1d53f121..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.pass.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// constexpr explicit sentinel(sentinel_t<Base> end);
-
-#include <cassert>
-#include <ranges>
-#include <tuple>
-#include <utility>
-
-struct Sent {
- int i;
-
- friend constexpr bool operator==(std::tuple<int>*, const Sent&) { return true; }
-};
-
-struct Range : std::ranges::view_base {
- std::tuple<int>* begin() const;
- Sent end();
-};
-
-// Test explicit
-
-static_assert(std::is_constructible_v<std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>, Sent>);
-static_assert(!std::is_convertible_v<Sent, std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>>);
-
-constexpr bool test() {
- // base is init correctly
- {
- using R = std::ranges::elements_view<Range, 0>;
- using Sentinel = std::ranges::sentinel_t<R>;
-
- Sentinel s1(Sent{5});
- assert(s1.base().i == 5);
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
index a8bc817ced291..ce81d1c00d376 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
@@ -72,9 +72,10 @@ constexpr bool test() {
using ConstSentinel = std::ranges::sentinel_t<const R>;
static_assert(!std::same_as<Sentinel, ConstSentinel>);
- Sentinel s1(Sent{5});
- ConstSentinel s2 = s1;
- assert(s2.base().i == 5);
+ // auto s1 = R{}.end();
+ // (void) s1;
+ // ConstSentinel s2 = s1;
+ // assert(s2.base().i == 5);
}
return true;
@@ -82,7 +83,7 @@ constexpr bool test() {
int main(int, char**) {
test();
- static_assert(test());
+ // static_assert(test());
return 0;
}
>From b4695a242823d5f4943d22cf64802696a092191c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 24 Apr 2026 07:04:24 +0300
Subject: [PATCH 11/28] Format
---
libcxx/docs/Status/Cxx26Papers.csv | 2 +-
.../range.elements/iterator/base.pass.cpp | 15 ++++++++-------
.../range.elements/sentinel/base.pass.cpp | 2 +-
.../range.split/iterator/base.pass.cpp | 10 +++++-----
.../range.split/iterator/deref.pass.cpp | 7 +++----
.../sentinel/ctor.convert.pass.cpp | 4 ++--
6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index 7fcebd331197b..ffa36d3f5145c 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -188,7 +188,7 @@
"`P4140R0 <https://wg21.link/P4140R0>`__","Proposed resolution for US70-126: allow incomplete types in type_order","2026-03 (Croydon)","","","`#189595 <https://github.com/llvm/llvm-project/issues/189595>`__",""
"`P3373R4 <https://wg21.link/P3373R4>`__","Of Operation States and Their Lifetimes","2026-03 (Croydon)","","","`#189597 <https://github.com/llvm/llvm-project/issues/189597>`__",""
"`P3986R1 <https://wg21.link/P3986R1>`__","A Wording Strategy for Inlinable Receivers","2026-03 (Croydon)","","","`#189598 <https://github.com/llvm/llvm-project/issues/189598>`__",""
-"`P3059R2 <https://wg21.link/P3059R2>`__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","","","`#189599 <https://github.com/llvm/llvm-project/issues/189599>`__",""
+"`P3059R2 <https://wg21.link/P3059R2>`__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","|Complete|","23","`#189599 <https://github.com/llvm/llvm-project/issues/189599>`__",""
"`P3725R3 <https://wg21.link/P3725R3>`__","Filter View Extensions for Safer Use, Rev 3","2026-03 (Croydon)","","","`#189601 <https://github.com/llvm/llvm-project/issues/189601>`__",""
"`P3828R1 <https://wg21.link/P3828R1>`__","Rename the to_input view to as_input","2026-03 (Croydon)","","","`#189602 <https://github.com/llvm/llvm-project/issues/189602>`__",""
"`P3795R2 <https://wg21.link/P3795R2>`__","Miscellaneous Reflection Cleanup","2026-03 (Croydon)","","","`#189603 <https://github.com/llvm/llvm-project/issues/189603>`__",""
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
index 425c13fea707e..316e3523edc73 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
@@ -40,14 +40,14 @@ constexpr bool test() {
// const &
{
const ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
- decltype(auto) base = it.base();
+ decltype(auto) base = it.base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
}
// &
{
- ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
+ ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = it.base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
@@ -55,7 +55,7 @@ constexpr bool test() {
// &&
{
- ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
+ ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>*>);
assert(base == &t);
@@ -64,7 +64,7 @@ constexpr bool test() {
// const &&
{
const ElementsIter it = std::ranges::elements_view<BaseView, 0>{BaseView{&t, &t + 1}}.begin();
- decltype(auto) base = std::move(it).base();
+ decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);
assert(base == &t);
}
@@ -81,9 +81,10 @@ constexpr bool test() {
using MoveOnlyElemIter =
std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>>;
- auto it = std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>{
- std::ranges::subrange{MoveOnlyIter{{}, MoveOnly{5}}, Sent{}}}
- .begin();
+ auto it =
+ std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>{
+ std::ranges::subrange{MoveOnlyIter{{}, MoveOnly{5}}, Sent{}}}
+ .begin();
decltype(auto) base = std::move(it).base();
static_assert(std::is_same_v<decltype(base), MoveOnlyIter>);
assert(base.mo.get() == 5);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
index a11d16817f030..885582a5c94a8 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
@@ -28,7 +28,7 @@ constexpr bool test() {
using EleSent = std::ranges::sentinel_t<EleRange>;
const EleRange ev;
- const EleSent st = ev.end();
+ const EleSent st = ev.end();
std::same_as<Sent> decltype(auto) base = st.base();
assert(base.i == 5);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
index 66c2914ba1919..fe9be0e97104c 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
@@ -16,7 +16,7 @@
#include "../types.h"
struct Iter : ForwardIterBase<Iter> {
- int i = 0;
+ int i = 0;
constexpr Iter() = default;
constexpr Iter(int ii) : i(ii) {}
constexpr int operator*() const { return i; }
@@ -42,28 +42,28 @@ constexpr bool test() {
// const &
{
- const SplitIter it = sv.begin();
+ const SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = it.base();
assert(base.i == 5);
}
// &
{
- SplitIter it = sv.begin();
+ SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = it.base();
assert(base.i == 5);
}
// &&
{
- SplitIter it = sv.begin();
+ SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = std::move(it).base();
assert(base.i == 5);
}
// const &&
{
- const SplitIter it = sv.begin();
+ const SplitIter it = sv.begin();
std::same_as<Iter> decltype(auto) base = std::move(it).base();
assert(base.i == 5);
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
index be7aca854f640..0e9812020fb38 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
@@ -17,7 +17,7 @@
#include "../types.h"
struct Iter : ForwardIterBase<Iter> {
- int i = 0;
+ int i = 0;
constexpr Iter() = default;
constexpr Iter(int ii) : i(ii) {}
constexpr int operator*() const { return i; }
@@ -37,9 +37,8 @@ constexpr bool test() {
using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
using SplitIter = std::ranges::iterator_t<SplitView>;
- SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}},
- std::ranges::subrange<Iter>{Iter{7}, Iter{8}}};
- const SplitIter it = sv.begin();
+ SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}}, std::ranges::subrange<Iter>{Iter{7}, Iter{8}}};
+ const SplitIter it = sv.begin();
std::same_as<std::ranges::subrange<Iter>> decltype(auto) value = *it;
assert(value.begin().i == 5);
assert(value.end().i == 7);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
index 0fffe9b508816..8a9ee79660a1d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
@@ -107,7 +107,7 @@ constexpr bool test() {
static_assert(!std::same_as<Sentinel, ConstSentinel>);
R r{TestRng{}, pred};
- Sentinel s1 = r.end();
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
int i = 10;
@@ -141,7 +141,7 @@ constexpr bool test() {
static_assert(!std::same_as<Sentinel, ConstSentinel>);
R r{Rng{}, TestPred{}};
- Sentinel s1 = r.end();
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
assert(s2.base().i == 0);
}
>From ee7863618f3b2d5bc4fc88409b2d77d0424444ec Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 17 Jul 2026 21:28:20 +0300
Subject: [PATCH 12/28] Release notes
---
libcxx/docs/ReleaseNotes/24.rst | 1 +
libcxx/docs/Status/Cxx26Papers.csv | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst
index 70c704ff9d326..052e5eab25433 100644
--- a/libcxx/docs/ReleaseNotes/24.rst
+++ b/libcxx/docs/ReleaseNotes/24.rst
@@ -39,6 +39,7 @@ Implemented Papers
------------------
- P0493R5: Atomic minimum/maximum (`Github <https://llvm.org/PR105418>`__)
+- P3059R2: Making user-defined constructors of view iterators/sentinels private (`Github <https://github.com/llvm/llvm-project/issues/189599>`__)
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index ffa36d3f5145c..4d0fbca940b92 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -188,7 +188,7 @@
"`P4140R0 <https://wg21.link/P4140R0>`__","Proposed resolution for US70-126: allow incomplete types in type_order","2026-03 (Croydon)","","","`#189595 <https://github.com/llvm/llvm-project/issues/189595>`__",""
"`P3373R4 <https://wg21.link/P3373R4>`__","Of Operation States and Their Lifetimes","2026-03 (Croydon)","","","`#189597 <https://github.com/llvm/llvm-project/issues/189597>`__",""
"`P3986R1 <https://wg21.link/P3986R1>`__","A Wording Strategy for Inlinable Receivers","2026-03 (Croydon)","","","`#189598 <https://github.com/llvm/llvm-project/issues/189598>`__",""
-"`P3059R2 <https://wg21.link/P3059R2>`__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","|Complete|","23","`#189599 <https://github.com/llvm/llvm-project/issues/189599>`__",""
+"`P3059R2 <https://wg21.link/P3059R2>`__","Making user-defined constructors of view iterators/sentinels private","2026-03 (Croydon)","|Complete|","24","`#189599 <https://github.com/llvm/llvm-project/issues/189599>`__",""
"`P3725R3 <https://wg21.link/P3725R3>`__","Filter View Extensions for Safer Use, Rev 3","2026-03 (Croydon)","","","`#189601 <https://github.com/llvm/llvm-project/issues/189601>`__",""
"`P3828R1 <https://wg21.link/P3828R1>`__","Rename the to_input view to as_input","2026-03 (Croydon)","","","`#189602 <https://github.com/llvm/llvm-project/issues/189602>`__",""
"`P3795R2 <https://wg21.link/P3795R2>`__","Miscellaneous Reflection Cleanup","2026-03 (Croydon)","","","`#189603 <https://github.com/llvm/llvm-project/issues/189603>`__",""
>From 11b36027bc4737a06ac1368d0c4027bead46a6c4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 17 Jul 2026 21:42:44 +0300
Subject: [PATCH 13/28] Format
---
.../range.adaptors/range.filter/iterator/arrow.pass.cpp | 3 ++-
.../range.adaptors/range.filter/iterator/deref.pass.cpp | 3 ++-
.../range.adaptors/range.split/iterator/base.pass.cpp | 3 +--
.../range.take.while/sentinel/ctor.convert.pass.cpp | 6 +++---
.../range.istream.view/iterator/deref.pass.cpp | 1 -
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
index 46d59c3de1d7d..284a22d218bf0 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp
@@ -88,7 +88,8 @@ constexpr void test() {
for (std::ptrdiff_t n = 0; n != 5; ++n) {
FilterView view = make_filter_view(array.data(), array.data() + array.size(), AlwaysTrue{});
FilterIterator iter = view.begin();
- for (std::ptrdiff_t i = 0; i < n; ++i) ++iter;
+ for (std::ptrdiff_t i = 0; i < n; ++i)
+ ++iter;
std::same_as<Iter> decltype(auto) result = iter.operator->();
assert(base(result) == array.data() + n);
assert(iter->x == n);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
index e794ff133dcb0..42b0f1816d8a1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp
@@ -37,7 +37,8 @@ constexpr void test() {
for (std::size_t n = 0; n != array.size(); ++n) {
FilterIterator iter = view.begin();
- for (std::size_t i = 0; i < n; ++i) ++iter;
+ for (std::size_t i = 0; i < n; ++i)
+ ++iter;
ValueType& result = *iter;
ASSERT_SAME_TYPE(ValueType&, decltype(*iter));
assert(&result == array.data() + n);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
index fe9be0e97104c..8e8eff8a12b97 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
@@ -37,8 +37,7 @@ constexpr bool test() {
using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
using SplitIter = std::ranges::iterator_t<SplitView>;
- SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}},
- std::ranges::subrange<Iter>{Iter{8}, Iter{9}}};
+ SplitView sv{std::ranges::subrange<Iter>{Iter{5}, Iter{8}}, std::ranges::subrange<Iter>{Iter{8}, Iter{9}}};
// const &
{
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
index 8a9ee79660a1d..1808545422498 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.convert.pass.cpp
@@ -82,7 +82,7 @@ constexpr bool test() {
static_assert(!std::same_as<Sentinel, ConstSentinel>);
R r{TestRng{}, nullptr};
- Sentinel s1 = r.end();
+ Sentinel s1 = r.end();
ConstSentinel s2 = s1;
assert(s2.base().i == 5);
}
@@ -110,8 +110,8 @@ constexpr bool test() {
Sentinel s1 = r.end();
ConstSentinel s2 = s1;
- int i = 10;
- int* iter = &i;
+ int i = 10;
+ int* iter = &i;
[[maybe_unused]] bool b = iter == s2;
assert(called);
}
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
index d010ee06dbf51..9f9f13399392c 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
@@ -28,7 +28,6 @@ void test() {
std::same_as<int&> decltype(auto) v1 = *it;
assert(v1 == 1);
}
-
}
int main(int, char**) {
>From 4127ad1211b268ab699b7c84aa543f8ce99fdc90 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 20 Jul 2026 14:02:29 +0300
Subject: [PATCH 14/28] Tests: `elements_view` updates
---
.../iterator/ctor.other.pass.cpp | 16 ++++++++++++----
.../sentinel/ctor.convert.pass.cpp | 18 ++++++++++++------
2 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
index d1b8ea73d635d..9255fb47013b6 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp
@@ -57,10 +57,18 @@ static_assert(!std::is_constructible_v<ConstElemIter<NonConvertibleView>, ElemIt
static_assert(!std::is_constructible_v<ElemIter<NonConvertibleView>, ConstElemIter<NonConvertibleView>>);
constexpr bool test() {
- // auto iter = std::ranges::elements_view<ConvertibleView, 0>{}.begin();
- // ConstElemIter<ConvertibleView> constIter = iter; // implicit
- // assert(constIter.base().movedFromOtherConst);
- // assert(constIter.base().i == 5);
+ struct TestRange : std::ranges::view_base {
+ constexpr ConvertibleIter<false> begin() { return ConvertibleIter<false>{5}; }
+ constexpr ConvertibleIter<false> end() { return ConvertibleIter<false>{5}; }
+ constexpr ConvertibleIter<true> begin() const { return ConvertibleIter<true>{5}; }
+ constexpr ConvertibleIter<true> end() const { return ConvertibleIter<true>{5}; }
+ };
+
+ std::ranges::elements_view<TestRange, 0> ev{TestRange{}};
+ ElemIter<TestRange> iter = ev.begin();
+ ConstElemIter<TestRange> constIter = iter; // implicit
+ assert(constIter.base().movedFromOtherConst);
+ assert(constIter.base().i == 5);
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
index ce81d1c00d376..25d1413b2fa16 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp
@@ -67,15 +67,21 @@ static_assert(
constexpr bool test() {
// base is init correctly
{
- using R = std::ranges::elements_view<Range, 0>;
+ struct TestRange : std::ranges::view_base {
+ constexpr std::tuple<int>* begin() const { return nullptr; }
+ constexpr Sent end() { return Sent{5}; }
+ constexpr ConstSent end() const { return ConstSent{5}; }
+ };
+
+ using R = std::ranges::elements_view<TestRange, 0>;
using Sentinel = std::ranges::sentinel_t<R>;
using ConstSentinel = std::ranges::sentinel_t<const R>;
static_assert(!std::same_as<Sentinel, ConstSentinel>);
- // auto s1 = R{}.end();
- // (void) s1;
- // ConstSentinel s2 = s1;
- // assert(s2.base().i == 5);
+ R r{TestRange{}};
+ Sentinel s1 = r.end();
+ ConstSentinel s2 = s1;
+ assert(s2.base().i == 5);
}
return true;
@@ -83,7 +89,7 @@ constexpr bool test() {
int main(int, char**) {
test();
- // static_assert(test());
+ static_assert(test());
return 0;
}
>From c33bac978f0ecf59b457c38f5a12c79c56af2fac Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 20 Jul 2026 14:03:34 +0300
Subject: [PATCH 15/28] Revert formatting
---
.../range.adaptors/range.elements/iterator/base.pass.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
index 316e3523edc73..27801eadac30f 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
@@ -22,7 +22,8 @@
// Test Noexcept
template <class T>
-concept IsBaseNoexcept = requires {
+concept IsBaseNoexcept =
+ requires {
{ std::declval<T>().base() } noexcept;
};
>From e35c0d0bed0d974cacdc104648177102db7dedbe Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Mon, 20 Jul 2026 15:24:00 +0300
Subject: [PATCH 16/28] Apply suggestion from @frederick-vs-ja
Co-authored-by: A. Jiang <de34 at live.cn>
---
.../range.adaptors/range.elements/iterator/base.pass.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
index 27801eadac30f..e28c36b1254af 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
@@ -79,9 +79,6 @@ constexpr bool test() {
constexpr bool operator==(const MoveOnlyIter&) const { return true; }
};
- using MoveOnlyElemIter =
- std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>>;
-
auto it =
std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>{
std::ranges::subrange{MoveOnlyIter{{}, MoveOnly{5}}, Sent{}}}
>From dc161708c53ce4ecf0b5596956eec6f7b03cfe36 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 21 Jul 2026 00:05:55 +0300
Subject: [PATCH 17/28] Fixed formatting
---
.../range.adaptors/range.elements/iterator/base.pass.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
index e28c36b1254af..bcce8e1f48f7b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/base.pass.cpp
@@ -22,8 +22,7 @@
// Test Noexcept
template <class T>
-concept IsBaseNoexcept =
- requires {
+concept IsBaseNoexcept = requires {
{ std::declval<T>().base() } noexcept;
};
>From f4d45145cd5092bb65a8137a243dc94a8e107812 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 21 Jul 2026 00:18:55 +0300
Subject: [PATCH 18/28] Enable test
---
.../ranges/range.adaptors/range.elements/sentinel/base.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
index 885582a5c94a8..114b7fc1f1b71 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/base.pass.cpp
@@ -37,6 +37,6 @@ constexpr bool test() {
int main(int, char**) {
test();
- // static_assert(test());
+ static_assert(test());
return 0;
}
>From 851f503a96a63350ca8f809a8c5deca584405d68 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 21 Jul 2026 07:53:40 +0300
Subject: [PATCH 19/28] Added `std::is_constructible/convertible` tests
---
.../iterator/ctor.base.compile.pass.cpp | 23 ++++++++++++
.../sentinel/ctor.base.compile.pass.cpp | 30 ++++++++++++++++
.../ctor.parent.iter.compile.pass.cpp | 25 +++++++++++++
.../sentinel/ctor.parent.compile.pass.cpp | 25 +++++++++++++
.../ctor.outer_iterator.compile.pass.cpp | 23 ++++++++++++
.../ctor.parent.base.compile.pass.cpp | 22 ++++++++++++
.../ctor.parent.compile.pass.cpp | 23 ++++++++++++
.../sentinel/ctor.base.pred.compile.pass.cpp | 35 +++++++++++++++++++
.../iterator/ctor.value.compile.pass.cpp | 26 ++++++++++++++
.../sentinel/ctor.value.compile.pass.cpp | 24 +++++++++++++
.../iterator/ctor.parent.compile.pass.cpp | 33 +++++++++++++++++
11 files changed, 289 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp
new file mode 100644
index 0000000000000..b43a60276e280
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.base.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit iterator(iterator_t<Base> current);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <tuple>
+#include <type_traits>
+
+using BaseIter = std::tuple<int>*;
+using ElementsIter = std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<BaseIter, BaseIter>, 0>>;
+
+static_assert(!std::is_constructible_v<ElementsIter, BaseIter>);
+static_assert(!std::is_convertible_v<BaseIter, ElementsIter>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp
new file mode 100644
index 0000000000000..ee4a297c1f4a9
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.base.compile.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(sentinel_t<Base> end);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+struct Sent {
+ int i;
+
+ friend constexpr bool operator==(std::tuple<int>*, const Sent&) { return true; }
+};
+
+struct Range : std::ranges::view_base {
+ std::tuple<int>* begin() const;
+ Sent end();
+};
+
+static_assert(!std::is_constructible_v<std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>, Sent>);
+static_assert(!std::is_convertible_v<Sent, std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
new file mode 100644
index 0000000000000..4a013d0072222
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr std::ranges::filter_view::<iterator>(filter_view&, iterator_t<V>);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "test_iterators.h"
+#include "../types.h"
+
+using View = minimal_view<int*, sentinel_wrapper<int*>>;
+using FilterView = std::ranges::filter_view<View, AlwaysTrue>;
+using FilterIterator = std::ranges::iterator_t<FilterView>;
+
+static_assert(!std::constructible_from<FilterIterator, FilterView>);
+static_assert(!std::convertible_to<FilterView, FilterIterator>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp
new file mode 100644
index 0000000000000..06e06aeb6db6e
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(filter_view&);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "test_iterators.h"
+#include "../types.h"
+
+using View = minimal_view<int*, sentinel_wrapper<int*>>;
+using FilterView = std::ranges::filter_view<View, AlwaysTrue>;
+using FilterSentinel = std::ranges::sentinel_t<FilterView>;
+
+static_assert(!std::constructible_from<FilterSentinel, FilterView>);
+static_assert(!std::convertible_to<FilterView, FilterSentinel>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..37fe2fadfd41a
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/ctor.outer_iterator.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit inner-iterator::inner-iterator(outer-iterator<Const> i);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "../types.h"
+
+static_assert(!std::is_constructible_v<InnerIterConst, OuterIterConst>);
+static_assert(!std::is_convertible_v<InnerIterConst, OuterIterConst>);
+
+static_assert(!std::is_constructible_v<InnerIterNonConst, OuterIterNonConst>);
+static_assert(!std::is_convertible_v<InnerIterNonConst, OuterIterNonConst>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp
new file mode 100644
index 0000000000000..70e97ea04f5c0
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.base.compile.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr outer-iterator(Parent& parent, iterator_t<Base> current);
+// requires forward_range<Base>
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+#include "../types.h"
+
+static_assert(std::ranges::forward_range<SplitViewForward>);
+static_assert(!std::is_constructible_v<OuterIterForward, SplitViewForward&, std::ranges::iterator_t<ForwardView>>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp
new file mode 100644
index 0000000000000..b838970718c8a
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/ctor.parent.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// explicit std::ranges::lazy_split_view::outer-iterator::outer-iterator(Parent& parent)
+// requires (!forward_range<Base>)
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+#include "../types.h"
+
+static_assert(!std::ranges::forward_range<SplitViewInput>);
+static_assert(!std::is_constructible_v<OuterIterInput, SplitViewInput&>);
+static_assert(!std::is_convertible_v<SplitViewInput&, OuterIterInput>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp
new file mode 100644
index 0000000000000..a66e3d1e84c6e
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pred.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+struct Sent {
+ int i;
+
+ friend constexpr bool operator==(int* iter, const Sent& s) { return s.i > *iter; }
+};
+
+struct Range : std::ranges::view_base {
+ int* begin() const;
+ Sent end();
+};
+
+struct Pred {
+ bool operator()(int i) const;
+};
+
+using Sentinel = std::ranges::sentinel_t<std::ranges::take_while_view<Range, Pred>>;
+
+static_assert(!std::is_constructible_v<Sentinel, std::ranges::sentinel_t<Range>, const Pred*>);
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
new file mode 100644
index 0000000000000..e95042e26e146
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit iterator(W value);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../types.h"
+
+static_assert(!std::is_constructible_v<std::ranges::iterator_t<std::ranges::iota_view<int>>, int>);
+
+using Iter = std::ranges::iterator_t<std::ranges::iota_view<SomeInt>>;
+static_assert(!std::is_constructible_v<Iter, SomeInt>);
+static_assert(!std::is_convertible_v<SomeInt, Iter>);
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
new file mode 100644
index 0000000000000..a39efb4318794
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(Bound bound);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../types.h"
+
+using Sent = std::ranges::sentinel_t<std::ranges::iota_view<SomeInt, IntSentinelWith<SomeInt>>>;
+static_assert(!std::is_constructible_v<Sent, IntSentinelWith<SomeInt>>);
+static_assert(!std::is_convertible_v<IntSentinelWith<SomeInt>, Sent>);
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
new file mode 100644
index 0000000000000..171e2dce1e5f0
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit iterator(basic_istream_view& parent) noexcept;
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <sstream>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// test that the constructor is explicit
+template <class CharT>
+using IstreamView = std::ranges::basic_istream_view<int, CharT>;
+template <class CharT>
+using Iter = std::ranges::iterator_t<IstreamView<CharT>>;
+
+static_assert(!std::constructible_from<Iter<char>, IstreamView<char>&>);
+static_assert(!std::convertible_to<IstreamView<char>&, Iter<char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::constructible_from<Iter<wchar_t>, IstreamView<wchar_t>&>);
+static_assert(!std::convertible_to<IstreamView<wchar_t>&, Iter<wchar_t>>);
+#endif
>From cfa8219f33f0d433afaa3144d3183bd763d58854 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 09:20:54 +0300
Subject: [PATCH 20/28] Cleanup
---
.../range.iota.view/iterator/ctor.value.compile.pass.cpp | 2 --
.../range.iota.view/sentinel/ctor.value.compile.pass.cpp | 2 --
2 files changed, 4 deletions(-)
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
index e95042e26e146..fc3384e191d1d 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.compile.pass.cpp
@@ -15,8 +15,6 @@
#include <ranges>
#include <type_traits>
-#include "test_macros.h"
-
#include "../types.h"
static_assert(!std::is_constructible_v<std::ranges::iterator_t<std::ranges::iota_view<int>>, int>);
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
index a39efb4318794..b0bcdb6c60ce7 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.compile.pass.cpp
@@ -15,8 +15,6 @@
#include <ranges>
#include <type_traits>
-#include "test_macros.h"
-
#include "../types.h"
using Sent = std::ranges::sentinel_t<std::ranges::iota_view<SomeInt, IntSentinelWith<SomeInt>>>;
>From 1438ff9824d09adb014641acc0ae3b0775ea8d27 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 10:42:42 +0300
Subject: [PATCH 21/28] Fixed CI
---
.../range.istream.view/iterator/ctor.parent.compile.pass.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
index 171e2dce1e5f0..04ff9ac24d731 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/ctor.parent.compile.pass.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-localization
// constexpr explicit iterator(basic_istream_view& parent) noexcept;
>From 98ad281967c925d3cbc27adaeabafeaddddd2227 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 10:57:29 +0300
Subject: [PATCH 22/28] Restored a test case!
---
.../range.istream.view/iterator/deref.pass.cpp | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
index 9f9f13399392c..5df730410a4ad 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/iterator/deref.pass.cpp
@@ -28,6 +28,17 @@ void test() {
std::same_as<int&> decltype(auto) v1 = *it;
assert(v1 == 1);
}
+
+ // operator* should return the same reference to the value stored in the view
+ {
+ auto iss = make_string_stream<CharT>("1 2 345 ");
+ std::ranges::basic_istream_view<int, CharT> isv{iss};
+ using Iter = std::ranges::iterator_t<decltype(isv)>;
+
+ Iter it1 = isv.begin();
+ Iter it2 = isv.begin();
+ assert(&*it1 == &*it2);
+ }
}
int main(int, char**) {
>From ea4f9412bc9b26b3ae55b40c23ee1ac615bbb643 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 11:16:34 +0300
Subject: [PATCH 23/28] Added a missing `take_view` test
---
.../ctor.base.compile.pass.cpp | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp
new file mode 100644
index 0000000000000..9383508165609
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/ctor.base.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(sentinel_t<Base> end);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+#include <type_traits>
+
+#include "test_iterators.h"
+#include "../types.h"
+
+using TakeView = std::ranges::take_view<MoveOnlyView>;
+using Sentinel = std::ranges::sentinel_t<TakeView>;
+
+static_assert(!std::is_constructible_v<Sentinel, sentinel_wrapper<int*>>);
+static_assert(!std::is_convertible_v<sentinel_wrapper<int*>, Sentinel>);
>From d0afec965397496a91848fdd2e46ed89c98e7039 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 11:34:21 +0300
Subject: [PATCH 24/28] Added missing test `join_view`
---
.../ctor.parent.compile.pass.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp
new file mode 100644
index 0000000000000..504c945e3d918
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/ctor.parent.compile.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(Parent& parent);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "../types.h"
+
+using Parent = std::ranges::join_view<ParentView<ChildView>>;
+static_assert(!std::is_constructible_v<std::ranges::sentinel_t<Parent>, Parent&>);
+static_assert(!std::is_convertible_v<std::ranges::sentinel_t<Parent>, Parent&>);
>From c50248da199d6cbb3d5ba6b292ef102e7e960d30 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 11:54:39 +0300
Subject: [PATCH 25/28] Update tests `split_view`
---
...tor.parent.iter.subrange.compile.pass.cpp} | 31 +++++------------
....pass.cpp => ctor.parent.compile.pass.cpp} | 34 ++++---------------
2 files changed, 14 insertions(+), 51 deletions(-)
rename libcxx/test/std/ranges/range.adaptors/range.split/iterator/{ctor.base.pass.cpp => ctor.parent.iter.subrange.compile.pass.cpp} (64%)
rename libcxx/test/std/ranges/range.adaptors/range.split/sentinel/{ctor.parent.pass.cpp => ctor.parent.compile.pass.cpp} (57%)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp
similarity index 64%
rename from libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
rename to libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp
index 823e22e117f77..9f4e9a13e0447 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.parent.iter.subrange.compile.pass.cpp
@@ -6,12 +6,14 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: std-at-least-c++20
-// constexpr iterator begin();
+// constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
-#include <cassert>
#include <ranges>
+#include <type_traits>
#include "../types.h"
@@ -30,24 +32,7 @@ struct TracedMoveView : std::ranges::view_base {
constexpr TracedMoveIter end() const { return {}; }
};
-constexpr bool test() {
- using SplitView = std::ranges::split_view<TracedMoveView, TracedMoveView>;
- using SplitIter = std::ranges::iterator_t<SplitView>;
-
- SplitView sv{TracedMoveView{}, TracedMoveView{}};
- SplitIter iter = sv.begin();
- assert(iter.base().moved);
-
- auto subRange = *iter;
- assert(subRange.begin().moved);
- assert(subRange.end().moved);
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
+using SplitView = std::ranges::split_view<TracedMoveView, TracedMoveView>;
+using SplitIter = std::ranges::iterator_t<SplitView>;
- return 0;
-}
+static_assert(!std::is_constructible_v<SplitIter, SplitView, TracedMoveIter, std::ranges::subrange<TracedMoveIter>>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
similarity index 57%
rename from libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
rename to libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
index 6e1ba912a201b..85d7e908a057c 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
@@ -6,41 +6,19 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: std-at-least-c++20
// constexpr explicit sentinel(split_view& parent);
-#include <cassert>
+// The constructor is now `private` (exposition-only) per P3059R2.
+
#include <ranges>
-#include <type_traits>
-#include "test_iterators.h"
+#include "../types.h"
-// test explicit
using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
using SplitSent = std::ranges::sentinel_t<SplitView>;
-constexpr bool test() {
- {
- int buffer[] = {0, 1, 2};
- Range input{buffer, sentinel_wrapper<int*>(buffer + 3)};
- SplitView sv(input, -1);
- auto it = sv.begin();
-
- auto sent = sv.end();
- assert(sent != it);
-
- ++it;
- assert(sent == it);
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
+static_assert(std::is_constructible_v<SplitSent, SplitView&>);
+static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
>From 50dc3e4c1aa67aa0e1b582eeecfbc904d7c80ef1 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 11:57:06 +0300
Subject: [PATCH 26/28] Fixed test
---
.../range.split/sentinel/ctor.parent.compile.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
index 85d7e908a057c..e0e8029c4c538 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.compile.pass.cpp
@@ -20,5 +20,5 @@ using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
using SplitSent = std::ranges::sentinel_t<SplitView>;
-static_assert(std::is_constructible_v<SplitSent, SplitView&>);
+static_assert(!std::is_constructible_v<SplitSent, SplitView&>);
static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
>From d93fdef4663517663ff4169230e6b2333f637d6e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 12:49:06 +0300
Subject: [PATCH 27/28] Added missing `transform_view` tests
---
.../ctor.parent.iter.compile.pass.cpp | 23 ++++++++++++++++++
.../sentinel/ctor.base.compile.pass.cpp | 24 +++++++++++++++++++
.../{iterator => sentinel}/sentinel.pass.cpp | 0
3 files changed, 47 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
rename libcxx/test/std/ranges/range.adaptors/range.transform/{iterator => sentinel}/sentinel.pass.cpp (100%)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp
new file mode 100644
index 0000000000000..e7841dede5bc2
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/ctor.parent.iter.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr iterator(Parent& parent, iterator_t<Base> current);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "../types.h"
+
+using TransformView = std::ranges::transform_view<MoveOnlyView, PlusOne>;
+using TransformViewBaseIter = std::ranges::iterator_t<MoveOnlyView>;
+using TransformIter = std::ranges::iterator_t<TransformView>;
+
+static_assert(!std::is_constructible_v<TransformIter, TransformView, TransformViewBaseIter>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
new file mode 100644
index 0000000000000..08be4bbd16667
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// constexpr explicit sentinel(sentinel_t<Base> end);
+
+// The constructor is now `private` (exposition-only) per P3059R2.
+
+#include <ranges>
+
+#include "../types.h"
+
+using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
+using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
+using SplitSent = std::ranges::sentinel_t<SplitView>;
+
+static_assert(!std::is_constructible_v<SplitSent, SplitView&>);
+static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/sentinel.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/sentinel.pass.cpp
similarity index 100%
rename from libcxx/test/std/ranges/range.adaptors/range.transform/iterator/sentinel.pass.cpp
rename to libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/sentinel.pass.cpp
>From 2b952f73eb09938ae7065c16560692152e4f0c50 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 22 Jul 2026 13:32:08 +0300
Subject: [PATCH 28/28] Try to fix the tests
---
.../iterator/ctor.parent.iter.compile.pass.cpp | 3 ++-
.../range.transform/sentinel/ctor.base.compile.pass.cpp | 9 +++++----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
index 4a013d0072222..bca1b3bda4b24 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent.iter.compile.pass.cpp
@@ -18,8 +18,9 @@
#include "../types.h"
using View = minimal_view<int*, sentinel_wrapper<int*>>;
+using ViewIter = std::ranges::iterator_t<View>;
using FilterView = std::ranges::filter_view<View, AlwaysTrue>;
using FilterIterator = std::ranges::iterator_t<FilterView>;
-static_assert(!std::constructible_from<FilterIterator, FilterView>);
+static_assert(!std::constructible_from<FilterIterator, FilterView, ViewIter>);
static_assert(!std::convertible_to<FilterView, FilterIterator>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
index 08be4bbd16667..25a73252bcd2e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/sentinel/ctor.base.compile.pass.cpp
@@ -14,11 +14,12 @@
#include <ranges>
-#include "../types.h"
-
+#include "test_iterators.h"
+
using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
+using RangeSent = std::ranges::sentinel_t<Range>;
using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
using SplitSent = std::ranges::sentinel_t<SplitView>;
-static_assert(!std::is_constructible_v<SplitSent, SplitView&>);
-static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
+static_assert(!std::is_constructible_v<SplitSent, RangeSent>);
+static_assert(!std::is_convertible_v<RangeSent, SplitSent>);
More information about the libcxx-commits
mailing list