[libcxx-commits] [libcxx] [libc++][ranges][enumerate_view] Update iterator `iter_move` test (PR #219474)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Sun Aug 30 19:01:12 PDT 2026


================
@@ -38,22 +44,51 @@ 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();
-
-  auto&& result = iter_move(it);
-
-  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())));
-
-  static_assert(noexcept(iter_move(it)) == HasNoexceptIterMove);
+  {
+    // 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();
+
+    auto&& result = iter_move(it);
+
+    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())));
+
+    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)));
+  }
+
+  {
+    // 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);
+    }
----------------
frederick-vs-ja wrote:

I don't think we should keep temporary objects living when asserting. Let's avoid local varibles.

```suggestion

    (void)std::ranges::iter_move(it);
    assert(r1.iter_move_called_times == 1);

    (void)std::ranges::iter_move(it);
    assert(r1.iter_move_called_times == 2);
```

https://github.com/llvm/llvm-project/pull/219474


More information about the libcxx-commits mailing list