[libcxx-commits] [libcxx] WIP [libc++][ranges] Applied [[nodiscard]] to `transform_view` (PR #204014)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jun 22 14:52:44 PDT 2026
https://github.com/lknknm updated https://github.com/llvm/llvm-project/pull/204014
>From e489902dd06c2ce3ce93b96c920c95d9ec8a039a Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 16 Jun 2026 00:40:45 +0200
Subject: [PATCH 01/17] apply: nodiscard to transform_view.h
---
libcxx/include/__ranges/transform_view.h | 60 ++++++++++++++----------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 98b38dd9b2aa1..7b4d5510376b2 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -88,43 +88,53 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interfac
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func)
: __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
- _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
requires copy_constructible<_View>
{
return __base_;
}
- _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator<false> begin() { return __iterator<false>{*this, ranges::begin(__base_)}; }
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator<true> begin() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator<false> begin() {
+ return __iterator<false>{*this, ranges::begin(__base_)};
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator<true> begin() const
requires range<const _View> && __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __iterator<true>(*this, ranges::begin(__base_));
}
- _LIBCPP_HIDE_FROM_ABI constexpr __sentinel<false> end() { return __sentinel<false>(ranges::end(__base_)); }
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator<false> end()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __sentinel<false> end() {
+ return __sentinel<false>(ranges::end(__base_));
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator<false> end()
requires common_range<_View>
{
return __iterator<false>(*this, ranges::end(__base_));
}
- _LIBCPP_HIDE_FROM_ABI constexpr __sentinel<true> end() const
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __sentinel<true> end() const
requires range<const _View> && __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __sentinel<true>(ranges::end(__base_));
}
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator<true> end() const
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator<true> end() const
requires common_range<const _View> && __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __iterator<true>(*this, ranges::end(__base_));
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
requires sized_range<_View>
{
return ranges::size(__base_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
requires sized_range<const _View>
{
return ranges::size(__base_);
@@ -209,11 +219,11 @@ class transform_view<_View, _Fn>::__iterator
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
- _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
- _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
- _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
noexcept(noexcept(std::invoke(*__parent_->__func_, *__current_))) {
return std::invoke(*__parent_->__func_, *__current_);
}
@@ -248,21 +258,21 @@ class transform_view<_View, _Fn>::__iterator
return __tmp;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
__current_ += __n;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
__current_ -= __n;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
noexcept(noexcept(std::invoke(*__parent_->__func_, __current_[__n])))
requires random_access_range<_Base>
{
@@ -305,25 +315,26 @@ class transform_view<_View, _Fn>::__iterator
return __x.__current_ <=> __y.__current_;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ + __n};
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ + __n};
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ - __n};
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
+ operator-(const __iterator& __x, const __iterator& __y)
requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y.__current_;
@@ -361,24 +372,25 @@ class transform_view<_View, _Fn>::__sentinel {
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__i.__end_)) {}
- _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
template <bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ == __y.__end_;
}
template <bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ - __y.__end_;
}
template <bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
return __x.__end_ - __y.__current_;
}
>From 2c54d6695b7e670e65481b6969c752bd931f9e67 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 16 Jun 2026 22:06:37 +0200
Subject: [PATCH 02/17] fix: remove [[nodiscard]] from operator+= and
operator-= to avoid false positives
---
libcxx/include/__ranges/transform_view.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 7b4d5510376b2..380346c1979c6 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -258,14 +258,14 @@ class transform_view<_View, _Fn>::__iterator
return __tmp;
}
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
__current_ += __n;
return *this;
}
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
__current_ -= __n;
>From 7611d0c56f5d8fe8fb7de2a11d46615c60097fe9 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <lucas at zuru.com>
Date: Wed, 17 Jun 2026 15:00:47 +0200
Subject: [PATCH 03/17] fix: remove [[nodiscard]] at it operator==
---
libcxx/include/__ranges/transform_view.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 380346c1979c6..25254cc684bd9 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -376,8 +376,7 @@ class transform_view<_View, _Fn>::__sentinel {
template <bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ == __y.__end_;
}
>From 6b9f7268e8e1ce9636faf835a18c280078800c29 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <lucas at zuru.com>
Date: Wed, 17 Jun 2026 17:31:19 +0200
Subject: [PATCH 04/17] rename: adaptor.nodiscard.verify.cpp to
nodiscard.verify.cpp
---
.../{adaptor.nodiscard.verify.cpp => nodiscard.verify.cpp} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename libcxx/test/libcxx/ranges/range.adaptors/range.transform/{adaptor.nodiscard.verify.cpp => nodiscard.verify.cpp} (100%)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
similarity index 100%
rename from libcxx/test/libcxx/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
>From 1e9875bda87483c2f3c2e9daa447dc84b57d1a56 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 17 Jun 2026 22:46:31 +0200
Subject: [PATCH 05/17] WIP: format existing tests with the addition of the
TestView
---
.../range.transform/nodiscard.verify.cpp | 30 +++++++++++++++----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 0a5fbf72a83ee..b41206cf55b7d 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -11,13 +11,33 @@
// Test the libc++ extension that std::views::transform is marked as [[nodiscard]].
#include <ranges>
+#include <functional>
+
+struct TestView : std::ranges::view_interface<TestView> {
+ int* begin();
+ char* begin() const;
+ const int* end();
+ const char* end() const;
+};
void test() {
int range[] = {1, 2, 3};
- auto f = [](int i) { return i; };
+ auto f = [](int i) { return i; };
+
+ auto identity_view = TestView{} | std::views::transform(std::identity{});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(f);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(range, f);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::transform(f);
- std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(range, f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- range | std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::all | std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::transform(f);
}
>From 4f97cc1846ac42765edd4dbdf25a19a85a6eea70 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 17 Jun 2026 22:56:51 +0200
Subject: [PATCH 06/17] WIP: ADL + CPO begin() and end() tests
---
.../range.transform/nodiscard.verify.cpp | 37 ++++++++++++++++++-
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index b41206cf55b7d..baef9f3857ae7 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -24,8 +24,9 @@ void test() {
int range[] = {1, 2, 3};
auto f = [](int i) { return i; };
- auto identity_view = TestView{} | std::views::transform(std::identity{});
-
+ auto identity_view = TestView{} | std::views::transform(std::identity{});
+ auto transformed_range = range | std::views::transform(f);
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
identity_view.begin();
@@ -40,4 +41,36 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::views::all | std::views::transform(f);
+
+ //===---------------------------------===//
+ //=== ADL-based begin() / end() ===//
+
+ using std::begin, std::end;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(transformed_range);
+
+ //===---------------------------------===//
+ //=== std::ranges CPO begin() / end() ===//
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(transformed_range);
}
>From 4d93776f19b5f07fed48c2d6750e6c37b3fb59b7 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 17 Jun 2026 23:08:28 +0200
Subject: [PATCH 07/17] WIP: add ADL + CPO size() tests
---
.../range.transform/nodiscard.verify.cpp | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index baef9f3857ae7..5569f72d84e67 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -45,20 +45,26 @@ void test() {
//===---------------------------------===//
//=== ADL-based begin() / end() ===//
- using std::begin, std::end;
+ using std::begin, std::end, std::size;
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
begin(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(identity_view);
+ begin(transformed_range);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(transformed_range);
+ end(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
end(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(transformed_range);
+
//===---------------------------------===//
//=== std::ranges CPO begin() / end() ===//
@@ -66,11 +72,17 @@ void test() {
std::ranges::begin(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(identity_view);
+ std::ranges::begin(transformed_range);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(transformed_range);
+ std::ranges::end(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::end(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(transformed_range);
}
>From e06d20fb65c87dda048fd720deaf9f8f3ca61e20 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 17 Jun 2026 23:10:13 +0200
Subject: [PATCH 08/17] WIP: small formatting tweaking for separator
---
.../range.adaptors/range.transform/nodiscard.verify.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 5569f72d84e67..1cb65c6c3e5e3 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -42,7 +42,7 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::views::all | std::views::transform(f);
- //===---------------------------------===//
+ //===---------------------------------------------------------------------------------------===//
//=== ADL-based begin() / end() ===//
using std::begin, std::end, std::size;
@@ -65,7 +65,7 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
size(transformed_range);
- //===---------------------------------===//
+ //===---------------------------------------------------------------------------------------===//
//=== std::ranges CPO begin() / end() ===//
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
>From 1536cf70f92dc55f9f2867dd5dc7be3d33940165 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Thu, 18 Jun 2026 21:42:15 +0200
Subject: [PATCH 09/17] =?UTF-8?q?add:=20const=20tests=20=E2=80=93=20all=20?=
=?UTF-8?q?passing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../range.transform/nodiscard.verify.cpp | 42 ++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 1cb65c6c3e5e3..35fb20569a002 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -25,7 +25,11 @@ void test() {
auto f = [](int i) { return i; };
auto identity_view = TestView{} | std::views::transform(std::identity{});
- auto transformed_range = range | std::views::transform(f);
+ auto transformed_range = range | std::views::transform(f);
+
+ const auto const_identity_view = TestView{} | std::views::transform(std::identity{});
+ const auto const_transformed_range = range | std::views::transform(f);
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
identity_view.begin();
@@ -53,11 +57,23 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
begin(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(const_transformed_range);
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
end(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
end(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(const_transformed_range);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
size(identity_view);
@@ -65,6 +81,12 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
size(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(const_transformed_range);
+
//===---------------------------------------------------------------------------------------===//
//=== std::ranges CPO begin() / end() ===//
@@ -74,15 +96,33 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::begin(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(const_transformed_range);
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::end(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::end(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(const_transformed_range);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::size(identity_view);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::ranges::size(transformed_range);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(const_transformed_range);
}
>From 1b7fc5d92ef3613cc155247598006a744590cb03 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Thu, 18 Jun 2026 22:19:45 +0200
Subject: [PATCH 10/17] add: sentinel-specific tests, it-specific tests + few
tweaks
---
.../range.transform/nodiscard.verify.cpp | 216 +++++++++++++-----
1 file changed, 164 insertions(+), 52 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 35fb20569a002..cbc996aa94e4c 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -25,15 +25,35 @@ void test() {
auto f = [](int i) { return i; };
auto identity_view = TestView{} | std::views::transform(std::identity{});
- auto transformed_range = range | std::views::transform(f);
+ auto transformed_range = range | std::views::transform(f);
const auto const_identity_view = TestView{} | std::views::transform(std::identity{});
const auto const_transformed_range = range | std::views::transform(f);
-
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
identity_view.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.end();
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::views::transform(f);
@@ -51,78 +71,170 @@ void test() {
using std::begin, std::end, std::size;
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(identity_view);
+ {
+ // ===== Non-const views =====
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(const_transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(transformed_range);
+ }
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(const_transformed_range);
+ {
+ // ===== Const views =====
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(const_identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ begin(const_transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(const_identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ end(const_transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(const_transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ size(const_transformed_range);
+ }
//===---------------------------------------------------------------------------------------===//
//=== std::ranges CPO begin() / end() ===//
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(identity_view);
+ {
+ // ===== Non-const views =====
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(const_transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(transformed_range);
+ }
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(const_transformed_range);
+ {
+ // ===== Const views =====
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(const_identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::begin(const_transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(const_identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(const_identity_view);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::end(const_transformed_range);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(const_transformed_range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(const_identity_view);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::size(const_transformed_range);
+ }
+
+ //===---------------------------------------------------------------------------------------===//
+ //=== Iterator-specific operations ===//
+ {
+ // ===== Non-const views =====
+ auto it = identity_view.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it.base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it + 1;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ 1 + it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - 1;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it[0];
+ }
+
+ {
+ // ===== Const views =====
+ const auto const_it = identity_view.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it.base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it + 1;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ 1 + const_it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it - 1;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it - const_it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *const_it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it[0];
+ }
+
+ //===---------------------------------------------------------------------------------------===//
+ //=== Sentinel-specific operations ===//
+ {
+ // ===== Non-const sentinels =====
+ auto transformed_range_sent = transformed_range.end();
+ auto identity_view_sent = identity_view.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range_sent.base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view_sent.base();
+ }
+
+ {
+ // ===== Const sentinels =====
+ const auto const_transformed_range_sent = transformed_range.end();
+ const auto const_identity_view_sent = identity_view.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range_sent.base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view_sent.base();
+ }
}
>From 8339556b6ccb5e2c496b9e9d467fa909bf9624fc Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Thu, 18 Jun 2026 22:20:40 +0200
Subject: [PATCH 11/17] nit: scope separation
---
.../range.transform/nodiscard.verify.cpp | 50 ++++++++++---------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index cbc996aa94e4c..20534abc3708a 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -30,41 +30,43 @@ void test() {
const auto const_identity_view = TestView{} | std::views::transform(std::identity{});
const auto const_transformed_range = range | std::views::transform(f);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view.begin();
+ {
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(f);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(range, f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(range, f);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- range | std::views::transform(f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::transform(f);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::all | std::views::transform(f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::transform(f);
+ }
//===---------------------------------------------------------------------------------------===//
//=== ADL-based begin() / end() ===//
>From c5fe3c8c5b2f44f4e40fb19eff64fc57ed009fab Mon Sep 17 00:00:00 2001
From: Lucas <github.snugness349 at passinbox.com>
Date: Fri, 19 Jun 2026 20:36:28 +0200
Subject: [PATCH 12/17] Update
libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
Co-authored-by: A. Jiang <de34 at live.cn>
---
.../ranges/range.adaptors/range.transform/nodiscard.verify.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 20534abc3708a..32704afa8b1b5 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: std-at-least-c++20
// Test the libc++ extension that std::views::transform is marked as [[nodiscard]].
>From 18c85f395623da36ba7e6cc4462f8672e99dda2d Mon Sep 17 00:00:00 2001
From: Lucas <github.snugness349 at passinbox.com>
Date: Fri, 19 Jun 2026 20:37:38 +0200
Subject: [PATCH 13/17] Update
libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
Co-authored-by: A. Jiang <de34 at live.cn>
---
.../ranges/range.adaptors/range.transform/nodiscard.verify.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 32704afa8b1b5..993715c120995 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -8,7 +8,7 @@
// REQUIRES: std-at-least-c++20
-// Test the libc++ extension that std::views::transform is marked as [[nodiscard]].
+// Test the libc++ extension that std::ranges::transform_view and std::views::transform are marked as [[nodiscard]].
#include <ranges>
#include <functional>
>From 54c7648de2dff1e92930adec6b03988bd7733a09 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Fri, 19 Jun 2026 22:38:05 +0200
Subject: [PATCH 14/17] WIP: slight reorder and removal of ADL + CPO tests
---
.../range.transform/nodiscard.verify.cpp | 162 ++++--------------
1 file changed, 29 insertions(+), 133 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 993715c120995..94ad431d792ea 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -30,144 +30,52 @@ void test() {
const auto const_identity_view = TestView{} | std::views::transform(std::identity{});
const auto const_transformed_range = range | std::views::transform(f);
- {
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view.begin();
+ auto it = identity_view.begin();
+ const auto const_it = identity_view.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view.begin();
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.begin();
+ auto transformed_range_sent = transformed_range.end();
+ auto identity_view_sent = identity_view.end();
+ const auto const_transformed_range_sent = transformed_range.end();
+ const auto const_identity_view_sent = identity_view.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_it.base();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it.base();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(identity_view, fn).base();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.begin();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ transformed_range.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(range, f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ identity_view.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- range | std::views::transform(f);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_transformed_range.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::all | std::views::transform(f);
- }
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const_identity_view.end();
- //===---------------------------------------------------------------------------------------===//
- //=== ADL-based begin() / end() ===//
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(f);
- using std::begin, std::end, std::size;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(range, f);
- {
- // ===== Non-const views =====
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(identity_view);
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(transformed_range);
- }
+ const_it[0];
- {
- // ===== Const views =====
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- begin(const_transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- end(const_transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- size(const_transformed_range);
- }
-
- //===---------------------------------------------------------------------------------------===//
- //=== std::ranges CPO begin() / end() ===//
-
- {
- // ===== Non-const views =====
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(transformed_range);
- }
-
- {
- // ===== Const views =====
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::begin(const_transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::end(const_transformed_range);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(const_identity_view);
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::ranges::size(const_transformed_range);
- }
-
- //===---------------------------------------------------------------------------------------===//
- //=== Iterator-specific operations ===//
{
// ===== Non-const views =====
- auto it = identity_view.begin();
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it.base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
it + 1;
@@ -189,11 +97,6 @@ void test() {
}
{
- // ===== Const views =====
- const auto const_it = identity_view.begin();
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it.base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
const_it + 1;
@@ -214,13 +117,8 @@ void test() {
const_it[0];
}
- //===---------------------------------------------------------------------------------------===//
- //=== Sentinel-specific operations ===//
{
// ===== Non-const sentinels =====
- auto transformed_range_sent = transformed_range.end();
- auto identity_view_sent = identity_view.end();
-
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
transformed_range_sent.base();
@@ -230,8 +128,6 @@ void test() {
{
// ===== Const sentinels =====
- const auto const_transformed_range_sent = transformed_range.end();
- const auto const_identity_view_sent = identity_view.end();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
const_transformed_range_sent.base();
>From d506e09c300a40e8414bf2e0cf856d83c8146d5d Mon Sep 17 00:00:00 2001
From: Lucas <github.snugness349 at passinbox.com>
Date: Sun, 21 Jun 2026 17:33:55 +0200
Subject: [PATCH 15/17] Update
libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
Co-authored-by: A. Jiang <de34 at live.cn>
---
.../ranges/range.adaptors/range.transform/nodiscard.verify.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 94ad431d792ea..65e07bcf7967c 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -71,7 +71,7 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::views::transform(range, f);
-
+// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
const_it[0];
{
>From b771a7db04a99d442061511c4ddcbb340542cbd9 Mon Sep 17 00:00:00 2001
From: Lucas <github.snugness349 at passinbox.com>
Date: Sun, 21 Jun 2026 17:34:30 +0200
Subject: [PATCH 16/17] Update
libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
Co-authored-by: Hristo Hristov <zingam at outlook.com>
---
.../ranges/range.adaptors/range.transform/nodiscard.verify.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 65e07bcf7967c..6176eca7223cb 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -118,7 +118,7 @@ void test() {
}
{
- // ===== Non-const sentinels =====
+ // Non-const sentinels
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
transformed_range_sent.base();
>From 2c4afe382238dd4423adbb765ec5c07215bd426c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Mon, 22 Jun 2026 23:51:46 +0200
Subject: [PATCH 17/17] fix + receive comments: tests now conforming to
remaining of nodiscard.verify.cpp tests
---
.../range.transform/nodiscard.verify.cpp | 133 ++++++------------
1 file changed, 42 insertions(+), 91 deletions(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 6176eca7223cb..0ecba943660d6 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -11,9 +11,10 @@
// Test the libc++ extension that std::ranges::transform_view and std::views::transform are marked as [[nodiscard]].
#include <ranges>
+#include <utility>
#include <functional>
-struct TestView : std::ranges::view_interface<TestView> {
+struct View : std::ranges::view_interface<View> {
int* begin();
char* begin() const;
const int* end();
@@ -21,118 +22,68 @@ struct TestView : std::ranges::view_interface<TestView> {
};
void test() {
- int range[] = {1, 2, 3};
- auto f = [](int i) { return i; };
+ auto v = View{} | std::views::transform(std::identity{});
- auto identity_view = TestView{} | std::views::transform(std::identity{});
- auto transformed_range = range | std::views::transform(f);
-
- const auto const_identity_view = TestView{} | std::views::transform(std::identity{});
- const auto const_transformed_range = range | std::views::transform(f);
-
- auto it = identity_view.begin();
- const auto const_it = identity_view.begin();
-
- auto transformed_range_sent = transformed_range.end();
- auto identity_view_sent = identity_view.end();
- const auto const_transformed_range_sent = transformed_range.end();
- const auto const_identity_view_sent = identity_view.end();
+ // [range.transform.view]
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it.base();
-
+ std::as_const(v).base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it.base();
+ std::move(v).base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(identity_view, fn).base();
-
+ v.begin();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.begin();
+ std::as_const(v).begin();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.begin();
-
+ v.end();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range.end();
+ std::as_const(v).end();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view.end();
-
+ v.size();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range.end();
+ std::as_const(v).size();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view.end();
+ // [range.transform.iterator]
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(f);
+ auto it = v.base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::transform(range, f);
-
-// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it[0];
-
- {
- // ===== Non-const views =====
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it + 1;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- 1 + it;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it - 1;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it - it;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- *it;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- it[0];
- }
-
- {
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it + 1;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- 1 + const_it;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it - 1;
-
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it - const_it;
+ std::as_const(it).base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(it).base();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- *const_it;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *it;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it[0];
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it + 0;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ 0 + it;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - 0;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - it;
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_it[0];
- }
+ // [range.transform.sentinel]
- {
- // Non-const sentinels
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- transformed_range_sent.base();
+ auto st = v.end();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- identity_view_sent.base();
- }
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ st.base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - st;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ st - it;
- {
- // ===== Const sentinels =====
+ // [range.transform.overview]
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_transformed_range_sent.base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(View{}, std::identity{});
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- const_identity_view_sent.base();
- }
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(std::identity{});
}
More information about the libcxx-commits
mailing list