[libcxx-commits] [libcxx] [libc++][ranges][enumerate_view] Fix iterator `iter_move` test (PR #219474)
Lucas Mellone via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 28 06:42:56 PDT 2026
https://github.com/lknknm 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/3] 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/3] 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/3] 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)));
More information about the libcxx-commits
mailing list