[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