[libcxx-commits] [libcxx] [libc++][mdspan] Add missing `std::move` in `std::extents` (PR #196574)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri May 8 09:43:36 PDT 2026
https://github.com/eiytoq created https://github.com/llvm/llvm-project/pull/196574
Without this fix, libc++ rejects this example:
```cpp
#include <mdspan>
struct RValueInt {
constexpr operator int() && noexcept { return 0; }
};
int main() {
std::extents<int, std::dynamic_extent> e(RValueInt{});
}
```
>From 861fa2f3c2981885b386efebd2ec8699f52580c2 Mon Sep 17 00:00:00 2001
From: eiytoq <eiytoq at outlook.com>
Date: Sat, 9 May 2026 00:32:19 +0800
Subject: [PATCH] [libc++][mdspan] Add missing std::move in std::extents
---
libcxx/include/__mdspan/extents.h | 2 +-
.../mdspan/extents/ctor_from_integral.pass.cpp | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index 379c762ace3ed..087be833cb439 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -322,7 +322,7 @@ class extents {
(is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
(sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
_LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
- : __vals_(static_cast<index_type>(__dynvals)...) {
+ : __vals_(static_cast<index_type>(std::move(__dynvals))...) {
// Not catching this could lead to out of bounds errors later
// e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp
index 24eb53b199338..ab8753faa7724 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp
@@ -38,6 +38,12 @@
#include "CtorTestCombinations.h"
#include "test_macros.h"
+struct RValueInt {
+ int val;
+ constexpr RValueInt(int v) : val(v) {}
+ constexpr operator int() && noexcept { return val; }
+};
+
struct IntegralCtorTest {
template <class E, class AllExtents, class Extents, size_t... Indices>
static constexpr void test_construction(AllExtents all_ext, Extents ext, std::index_sequence<Indices...>) {
@@ -47,6 +53,12 @@ struct IntegralCtorTest {
}
};
+constexpr bool test_rvalue_conversion() {
+ std::dextents<int, 1> e(RValueInt{1});
+ assert(e.extent(0) == 1);
+ return true;
+}
+
int main(int, char**) {
test_index_type_combo<IntegralCtorTest>();
static_assert(test_index_type_combo<IntegralCtorTest>());
@@ -65,5 +77,9 @@ int main(int, char**) {
static_assert(std::is_convertible_v<IntType, int>, "Test helper IntType unexpectedly not convertible to int");
static_assert(!std::is_constructible_v< std::extents<unsigned long, D>, IntType>,
"extents constructible from illegal arguments");
+
+ test_rvalue_conversion();
+ static_assert(test_rvalue_conversion());
+
return 0;
}
More information about the libcxx-commits
mailing list