[libcxx-commits] [libcxx] [libc++][ranges][enumerate_view] Update iterator `iter_move` test (PR #219474)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Aug 29 00:44:07 PDT 2026
https://github.com/Zingam updated https://github.com/llvm/llvm-project/pull/219474
>From 92f4c7a8395330e3ee69c772ff6f7e0a559e6ec0 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 28 Aug 2026 15:31:24 +0200
Subject: [PATCH 1/6] add: is_nothrow_move_constructible test case
---
.../iterator/iter_move.pass.cpp | 34 ++++++++++++++-----
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index ed28662a8a5eb..57f7fce0e4312 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -29,6 +29,11 @@
#include "../types.h"
+struct ThrowingMove {
+ ThrowingMove() = default;
+ ThrowingMove(ThrowingMove&&) {}
+};
+
template <class Iterator, bool HasNoexceptIterMove>
constexpr void test() {
using Sentinel = sentinel_wrapper<Iterator>;
@@ -38,19 +43,30 @@ constexpr void test() {
std::array array{0, 1, 2, 3, 4};
- View mv{Iterator(std::to_address(base(array.begin()))), Sentinel(Iterator(std::to_address(base(array.end()))))};
- EnumerateView ev{std::move(mv)};
- EnumerateIterator const it = ev.begin();
+ {
+ View mv{Iterator(std::to_address(base(array.begin()))), Sentinel(Iterator(std::to_address(base(array.end()))))};
+ EnumerateView ev{std::move(mv)};
+ EnumerateIterator const it = ev.begin();
+
+ auto&& result = iter_move(it);
- auto&& result = iter_move(it);
+ using DifferenceT = std::iter_difference_t<EnumerateIterator>;
+ static_assert(std::is_same_v<decltype(result), std::tuple<DifferenceT, int&&>&&>);
- using DifferenceT = std::iter_difference_t<EnumerateIterator>;
- static_assert(std::is_same_v<decltype(result), std::tuple<DifferenceT, int&&>&&>);
+ assert(get<0>(result) == 0);
+ assert(&get<1>(result) == std::to_address(base(array.begin())));
- assert(get<0>(result) == 0);
- assert(&get<1>(result) == std::to_address(base(array.begin())));
+ static_assert(noexcept(iter_move(it)) == HasNoexceptIterMove);
+ }
- static_assert(noexcept(iter_move(it)) == HasNoexceptIterMove);
+ {
+ // !is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>
+ // underlying iter_move may throw
+ auto throwingMoveRange = std::views::iota(0, 9) | std::views::transform([](auto) noexcept { return ThrowingMove{}; });
+ std::ranges::enumerate_view v(throwingMoveRange);
+ auto it = v.begin();
+ static_assert(!noexcept(std::ranges::iter_move(it)));
+ }
}
constexpr bool tests() {
>From 14126502ad44f5639542366a2a62e9f07a31725c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 28 Aug 2026 15:36:43 +0200
Subject: [PATCH 2/6] add: underlying iterator iter_move is called through
ranges::iter_move
---
.../iterator/iter_move.pass.cpp | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index 57f7fce0e4312..2a9b462717711 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -28,6 +28,7 @@
#include "test_iterators.h"
#include "../types.h"
+#include "../../range_adaptor_types.h"
struct ThrowingMove {
ThrowingMove() = default;
@@ -44,6 +45,7 @@ constexpr void test() {
std::array array{0, 1, 2, 3, 4};
{
+ // underlying iter_move noexcept
View mv{Iterator(std::to_address(base(array.begin()))), Sentinel(Iterator(std::to_address(base(array.end()))))};
EnumerateView ev{std::move(mv)};
EnumerateIterator const it = ev.begin();
@@ -67,6 +69,22 @@ constexpr void test() {
auto it = v.begin();
static_assert(!noexcept(std::ranges::iter_move(it)));
}
+
+ {
+ // underlying iterator iter_move is called through ranges::iter_move
+ adltest::IterMoveSwapRange r1{};
+ assert(r1.iter_move_called_times == 0);
+ std::ranges::enumerate_view v(r1);
+ auto it = v.begin();
+ {
+ [[maybe_unused]] auto&& i = std::ranges::iter_move(it);
+ assert(r1.iter_move_called_times == 1);
+ }
+ {
+ [[maybe_unused]] auto&& i = std::ranges::iter_move(it);
+ assert(r1.iter_move_called_times == 2);
+ }
+ }
}
constexpr bool tests() {
>From 8b15a9b3394a42b4ac3cb26b84c895ae0dfc1b89 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 28 Aug 2026 15:42:43 +0200
Subject: [PATCH 3/6] fix: clang-format
---
.../range.adaptors/range.enumerate/iterator/iter_move.pass.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index 2a9b462717711..e401f3525509c 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -64,7 +64,8 @@ constexpr void test() {
{
// !is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>
// underlying iter_move may throw
- auto throwingMoveRange = std::views::iota(0, 9) | std::views::transform([](auto) noexcept { return ThrowingMove{}; });
+ auto throwingMoveRange =
+ std::views::iota(0, 9) | std::views::transform([](auto) noexcept { return ThrowingMove{}; });
std::ranges::enumerate_view v(throwingMoveRange);
auto it = v.begin();
static_assert(!noexcept(std::ranges::iter_move(it)));
>From 1ee74db9f194ec599c3d127512b22dca87ce8c0c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 28 Aug 2026 15:45:09 +0200
Subject: [PATCH 4/6] fix: clang-format trailing space
---
.../range.adaptors/range.enumerate/iterator/iter_move.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index e401f3525509c..52ef63407dd2a 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -64,7 +64,7 @@ constexpr void test() {
{
// !is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>
// underlying iter_move may throw
- auto throwingMoveRange =
+ auto throwingMoveRange =
std::views::iota(0, 9) | std::views::transform([](auto) noexcept { return ThrowingMove{}; });
std::ranges::enumerate_view v(throwingMoveRange);
auto it = v.begin();
>From cee9cdf114612fd8b386ef6b7e8a990bac508260 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Sat, 29 Aug 2026 10:43:00 +0300
Subject: [PATCH 5/6] Apply batched suggestions from code review
Co-authored-by: Hristo Hristov <hghristov.rmm at gmail.com>
Co-authored-by: Hristo Hristov <zingam at outlook.com>
---
.../range.enumerate/iterator/iter_move.pass.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index 52ef63407dd2a..698da210bccca 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -45,7 +45,7 @@ constexpr void test() {
std::array array{0, 1, 2, 3, 4};
{
- // underlying iter_move noexcept
+ // Underlying iter_move may not trow.
View mv{Iterator(std::to_address(base(array.begin()))), Sentinel(Iterator(std::to_address(base(array.end()))))};
EnumerateView ev{std::move(mv)};
EnumerateIterator const it = ev.begin();
@@ -63,7 +63,7 @@ constexpr void test() {
{
// !is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>
- // underlying iter_move may throw
+ // underlying iter_move may throw.
auto throwingMoveRange =
std::views::iota(0, 9) | std::views::transform([](auto) noexcept { return ThrowingMove{}; });
std::ranges::enumerate_view v(throwingMoveRange);
@@ -72,7 +72,7 @@ constexpr void test() {
}
{
- // underlying iterator iter_move is called through ranges::iter_move
+ // Underlying iterator iter_move is called through ranges::iter_move.
adltest::IterMoveSwapRange r1{};
assert(r1.iter_move_called_times == 0);
std::ranges::enumerate_view v(r1);
@@ -88,7 +88,7 @@ constexpr void test() {
}
}
-constexpr bool tests() {
+constexpr bool test() {
// clang-format off
test<cpp17_input_iterator<int*>, /* noexcept */ false>();
test<cpp20_input_iterator<int*>, /* noexcept */ false>();
@@ -106,7 +106,8 @@ constexpr bool tests() {
int main(int, char**) {
tests();
- static_assert(tests());
+test();
+static_assert(test());
return 0;
}
>From 17158f289ae44e37180232301254d562ab3cf20b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Sat, 29 Aug 2026 10:43:57 +0300
Subject: [PATCH 6/6] Apply suggestion from @Zingam
---
.../range.enumerate/iterator/iter_move.pass.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
index 698da210bccca..272be5d55fb72 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/iterator/iter_move.pass.cpp
@@ -106,8 +106,8 @@ constexpr bool test() {
int main(int, char**) {
tests();
-test();
-static_assert(test());
+ test();
+ static_assert(test());
return 0;
}
More information about the libcxx-commits
mailing list