[libcxx-commits] [libcxx] WIP [libc++][ranges] Applied [[nodiscard]] to `adjacent_view` (PR #205206)

Lucas Mellone via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 24 13:46:52 PDT 2026


https://github.com/lknknm updated https://github.com/llvm/llvm-project/pull/205206

>From ac484ba7e5d1d4a952002aff17a9b988383e4ff5 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 23 Jun 2026 00:30:35 +0200
Subject: [PATCH 1/8] wip: initial nodiscard apply

---
 libcxx/include/__ranges/adjacent_view.h | 36 +++++++++++++------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index 40474b85c794f..e3052d48fdac5 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -81,26 +81,26 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
 
   _LIBCPP_HIDE_FROM_ABI constexpr explicit adjacent_view(_View __base) : __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_); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
     requires(!__simple_view<_View>)
   {
     return __iterator<false>(ranges::begin(__base_), ranges::end(__base_));
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
     requires range<const _View> // LWG4482 This is under-constrained.
   {
     return __iterator<true>(ranges::begin(__base_), ranges::end(__base_));
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end()
     requires(!__simple_view<_View>)
   {
     if constexpr (common_range<_View>) {
@@ -110,7 +110,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
     }
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
     requires range<const _View> // LWG4482 This is under-constrained.
   {
     if constexpr (common_range<const _View>) {
@@ -120,7 +120,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
     }
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
     requires sized_range<_View>
   {
     using _ST = decltype(ranges::size(__base_));
@@ -130,7 +130,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
     return static_cast<_ST>(__sz);
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
     requires sized_range<const _View>
   {
     using _ST = decltype(ranges::size(__base_));
@@ -143,7 +143,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
 
 struct __adjacent_view_iter_access {
   template <class _Iter>
-  _LIBCPP_HIDE_FROM_ABI constexpr static auto& __get_current(_Iter& __it) noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static auto& __get_current(_Iter& __it) noexcept {
     return __it.__current_;
   }
 };
@@ -157,13 +157,14 @@ class adjacent_view<_View, _Np>::__iterator {
   using _Base _LIBCPP_NODEBUG              = __maybe_const<_Const, _View>;
   array<iterator_t<_Base>, _Np> __current_ = array<iterator_t<_Base>, _Np>();
 
-  _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
     __current_[0] = __first;
     for (size_t __i = 1; __i < _Np; ++__i) {
       __current_[__i] = ranges::next(__current_[__i - 1], 1, __last);
     }
   }
 
+  [[nodiscard]]
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) {
     if constexpr (!bidirectional_range<_Base>) {
       __current_.fill(__last);
@@ -257,7 +258,7 @@ class adjacent_view<_View, _Np>::__iterator {
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
     requires random_access_range<_Base>
   {
     return std::__tuple_transform([&](auto& __i) -> decltype(auto) { return __i[__n]; }, __current_);
@@ -297,7 +298,7 @@ class adjacent_view<_View, _Np>::__iterator {
     return __x.__current_.back() <=> __y.__current_.back();
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
     requires random_access_range<_Base>
   {
     auto __r = __i;
@@ -305,13 +306,13 @@ class adjacent_view<_View, _Np>::__iterator {
     return __r;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
     requires random_access_range<_Base>
   {
     return __i + __n;
   }
 
-  _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
     requires random_access_range<_Base>
   {
     auto __r = __i;
@@ -319,7 +320,8 @@ class adjacent_view<_View, _Np>::__iterator {
     return __r;
   }
 
-  _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_.back() - __y.__current_.back();
@@ -389,12 +391,12 @@ template <size_t _Np>
 struct __fn : __range_adaptor_closure<__fn<_Np>> {
   template <class _Range>
     requires(_Np == 0 && forward_range<_Range &&>)
-  _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&&) noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&&) noexcept {
     return empty_view<tuple<>>{};
   }
 
   template <class _Ranges>
-  _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ranges&& __range) noexcept(
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ranges&& __range) noexcept(
       noexcept(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))))
       -> decltype(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))) {
     return adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range));

>From 0658b8de94319d0f5ab15b0effff5054ced745d9 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 23 Jun 2026 22:36:30 +0200
Subject: [PATCH 2/8] wip: complete nodiscard to adjacent_view.h; tests
 remaining

---
 libcxx/include/__ranges/adjacent_view.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index e3052d48fdac5..efc113b1f4d39 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -86,6 +86,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
   {
     return __base_;
   }
+
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
 
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
@@ -180,7 +181,7 @@ class adjacent_view<_View, _Np>::__iterator {
   _LIBCPP_HIDE_FROM_ABI explicit constexpr __iterator(_Iter&& __i, index_sequence<_Is...>)
       : __current_{std::move(__i.__current_[_Is])...} {}
 
-  static consteval auto __get_iterator_concept() {
+  [[nodiscard]] static consteval auto __get_iterator_concept() {
     if constexpr (random_access_range<_Base>)
       return random_access_iterator_tag{};
     else if constexpr (bidirectional_range<_Base>)
@@ -206,7 +207,7 @@ class adjacent_view<_View, _Np>::__iterator {
     requires _Const && convertible_to<iterator_t<_View>, iterator_t<const _View>>
       : __iterator(std::move(__i), make_index_sequence<_Np>{}) {}
 
-  _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
     return std::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
   }
 
@@ -368,15 +369,15 @@ class adjacent_view<_View, _Np>::__sentinel {
 
   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_.back() - __y.__end_;
   }
 
   template <bool _OtherConst>
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
-  _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
-  operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 
+  operator-(const __sentinel & __y, const __iterator<_OtherConst>& __x) {
     return __y.__end_ - __x.__current_.back();
   }
 };

>From 5d963629251c787691c3799d62553c33f8497828 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 23 Jun 2026 23:11:13 +0200
Subject: [PATCH 3/8] add: test file

---
 .../range.adjacent/nodiscard.verify.cpp               | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp

diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..fae42d0e5ccaa
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// Test the libc++ extension that std::ranges::adjacent_view and std::views::adjacent are marked as [[nodiscard]].

>From 34f7490155246de57581731191026bcab66936a1 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Tue, 23 Jun 2026 23:39:13 +0200
Subject: [PATCH 4/8] move: nodiscard test folder

---
 .../range.adjacent/nodiscard.verify.cpp       | 35 +++++++++++++++++++
 .../range.adjacent/nodiscard.verify.cpp       | 11 ------
 2 files changed, 35 insertions(+), 11 deletions(-)
 create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
 delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp

diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..fcbbe3605fe31
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// Test the libc++ extension that std::ranges::adjacent_view and std::views::adjacent are marked as [[nodiscard]].
+#include <ranges>
+#include <utility>
+#include <functional>
+
+#include "test_iterators.h"
+
+template<size_t N>
+    requires (N > 0)
+struct NonCommonSimpleView<N> : std::ranges::adjacent_view<NonCommonSimpleView, N> {
+  int* begin();
+  int* begin() const;
+  sized_sentinel<int*> end();
+  sized_sentinel<int*> end() const;
+};
+
+static_assert(!std::ranges::common_range<View>);
+static_assert(
+    std::same_as<std::ranges::iterator_t<NonCommonSimpleView>, std::ranges::iterator_t<const NonCommonSimpleView>>);
+static_assert(
+    std::same_as<std::ranges::sentinel_t<NonCommonSimpleView>, std::ranges::sentinel_t<const NonCommonSimpleView>>);
+
+void test() {
+  auto v = NonCommonSimpleView<2>{} | std::views::transform(std::identity{});
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
deleted file mode 100644
index fae42d0e5ccaa..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: std-at-least-c++20
-
-// Test the libc++ extension that std::ranges::adjacent_view and std::views::adjacent are marked as [[nodiscard]].

>From 5106b0aaa8a7d1d417b502f3e5c8519e0912e252 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 24 Jun 2026 20:56:15 +0200
Subject: [PATCH 5/8] fix: view for tests

---
 .../range.adjacent/nodiscard.verify.cpp       | 26 +++++--------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
index fcbbe3605fe31..f9eb228cd55ec 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -11,25 +11,13 @@
 // Test the libc++ extension that std::ranges::adjacent_view and std::views::adjacent are marked as [[nodiscard]].
 #include <ranges>
 #include <utility>
-#include <functional>
-
-#include "test_iterators.h"
-
-template<size_t N>
-    requires (N > 0)
-struct NonCommonSimpleView<N> : std::ranges::adjacent_view<NonCommonSimpleView, N> {
-  int* begin();
-  int* begin() const;
-  sized_sentinel<int*> end();
-  sized_sentinel<int*> end() const;
-};
-
-static_assert(!std::ranges::common_range<View>);
-static_assert(
-    std::same_as<std::ranges::iterator_t<NonCommonSimpleView>, std::ranges::iterator_t<const NonCommonSimpleView>>);
-static_assert(
-    std::same_as<std::ranges::sentinel_t<NonCommonSimpleView>, std::ranges::sentinel_t<const NonCommonSimpleView>>);
 
 void test() {
-  auto v = NonCommonSimpleView<2>{} | std::views::transform(std::identity{});
+  int range[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+  auto v      = range | std::views::adjacent<2>;
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::as_const(v).base();
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::move(v).base();
 }

>From 7ed49fb8ae31e5cae5d325dc64b9553a841627fb Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 24 Jun 2026 21:35:49 +0200
Subject: [PATCH 6/8] add: iterator tests. remove mistaken nodiscard from ctor

---
 libcxx/include/__ranges/adjacent_view.h       |  7 ++--
 .../range.adjacent/nodiscard.verify.cpp       | 39 +++++++++++++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index efc113b1f4d39..847efcaedf711 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -158,14 +158,13 @@ class adjacent_view<_View, _Np>::__iterator {
   using _Base _LIBCPP_NODEBUG              = __maybe_const<_Const, _View>;
   array<iterator_t<_Base>, _Np> __current_ = array<iterator_t<_Base>, _Np>();
 
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
+  _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
     __current_[0] = __first;
     for (size_t __i = 1; __i < _Np; ++__i) {
       __current_[__i] = ranges::next(__current_[__i - 1], 1, __last);
     }
   }
 
-  [[nodiscard]]
   _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) {
     if constexpr (!bidirectional_range<_Base>) {
       __current_.fill(__last);
@@ -376,8 +375,8 @@ class adjacent_view<_View, _Np>::__sentinel {
 
   template <bool _OtherConst>
     requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 
-  operator-(const __sentinel & __y, const __iterator<_OtherConst>& __x) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+  operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
     return __y.__end_ - __x.__current_.back();
   }
 };
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
index f9eb228cd55ec..4e64b32b8fcf7 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -16,8 +16,47 @@ void test() {
   int range[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   auto v      = range | std::views::adjacent<2>;
 
+  // [range.adjacent.view]
+
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::as_const(v).base();
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::move(v).base();
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.begin();
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::as_const(v).begin();
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.end();
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::as_const(v).end();
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  v.size();
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::as_const(v).size();
+
+  // [range.adjacent.iterator]
+
+  auto it = v.begin();
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::ranges::__adjacent_view_iter_access::__get_current(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}}
+  std::as_const(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;
 }

>From d99e0ed03bdc5841c893d29768fcb4774ee189da Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 24 Jun 2026 22:27:23 +0200
Subject: [PATCH 7/8] add: sentinel tests

---
 .../range.adjacent/nodiscard.verify.cpp         | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
index 4e64b32b8fcf7..8c4f6d619879f 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -59,4 +59,21 @@ void test() {
   it - 0;
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   it - it;
+
+  // [range.adjacent.sentinel]
+
+  auto st = v.end();
+
+  // 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;
+
+  auto c_it = std::as_const(v).begin();
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  st - c_it;
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  c_it - st;
+
 }

>From e3f2651a69c1001b7653d72879c5f95e63f5b30c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <sxswt at protonmail.com>
Date: Wed, 24 Jun 2026 22:46:05 +0200
Subject: [PATCH 8/8] add: CPO tests

---
 .../range.adaptors/range.adjacent/nodiscard.verify.cpp     | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
index 8c4f6d619879f..3c3a2aa2cef0e 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -76,4 +76,11 @@ void test() {
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   c_it - st;
 
+  // [range.adjacent.overview]
+    
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::views::adjacent<0>(range);
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::views::adjacent<2>(range);
 }



More information about the libcxx-commits mailing list