aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaoyang Liu <siujoeng.lau@gmail.com>2024-06-25 08:20:14 -0700
committerGitHub <noreply@github.com>2024-06-25 10:20:14 -0500
commit8c11d3788c26cd85f102959068109d3e498e8498 (patch)
tree52f1a1e9ef4528b40acbda885bae688c1ff4ce77
parent8a46bbbc22a51db57f05beb0026772b899a785b9 (diff)
downloadllvm-8c11d3788c26cd85f102959068109d3e498e8498.zip
llvm-8c11d3788c26cd85f102959068109d3e498e8498.tar.gz
llvm-8c11d3788c26cd85f102959068109d3e498e8498.tar.bz2
[libc++] P3029R1: Better `mdspan`'s CTAD - `std::extents` (#89015)
This patch implements an improvement introduced in P3029R1 that was missed in #87873. It adds a deduction of static extents if integral_constant-like constants are passed to `std::extents`.
-rw-r--r--libcxx/include/__mdspan/extents.h9
-rw-r--r--libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp13
2 files changed, 20 insertions, 2 deletions
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index ddf9fab..fea0dec 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -455,8 +455,15 @@ template <class _IndexType, size_t _Rank>
using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type;
// Deduction guide for extents
+# if _LIBCPP_STD_VER >= 26
template <class... _IndexTypes>
-extents(_IndexTypes...) -> extents<size_t, size_t(((void)sizeof(_IndexTypes), dynamic_extent))...>;
+ requires(is_convertible_v<_IndexTypes, size_t> && ...)
+explicit extents(_IndexTypes...) -> extents<size_t, __maybe_static_ext<_IndexTypes>...>;
+# else
+template <class... _IndexTypes>
+ requires(is_convertible_v<_IndexTypes, size_t> && ...)
+explicit extents(_IndexTypes...) -> extents<size_t, size_t(((void)sizeof(_IndexTypes), dynamic_extent))...>;
+# endif
namespace __mdspan_detail {
diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp
index 3f99d8a..9144bb6 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp
@@ -13,10 +13,12 @@
// explicit extents(Integrals...) -> see below;
// Constraints: (is_convertible_v<Integrals, size_t> && ...) is true.
//
-// Remarks: The deduced type is dextents<size_t, sizeof...(Integrals)>.
+// Remarks: The deduced type is dextents<size_t, sizeof...(Integrals)>. // until C++26
+// Remarks: The deduced type is extents<size_t, maybe-static-ext<Integrals>...>. // since C++26
#include <mdspan>
#include <cassert>
+#include <type_traits>
#include "../ConvertibleToIntegral.h"
#include "test_macros.h"
@@ -43,6 +45,15 @@ constexpr bool test() {
test(std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9),
std::extents<std::size_t, D, D, D, D, D, D, D, D, D>(1, 2u, 3, 4, 5, 6, 7, 8, 9));
test(std::extents(NoDefaultCtorIndex{1}, NoDefaultCtorIndex{2}), std::extents<std::size_t, D, D>(1, 2));
+
+#if _LIBCPP_STD_VER >= 26
+ // P3029R1: deduction from `integral_constant`
+ test(std::extents(std::integral_constant<size_t, 5>{}), std::extents<std::size_t, 5>());
+ test(std::extents(std::integral_constant<size_t, 5>{}, 6), std::extents<std::size_t, 5, std::dynamic_extent>(6));
+ test(std::extents(std::integral_constant<size_t, 5>{}, 6, std::integral_constant<size_t, 7>{}),
+ std::extents<std::size_t, 5, std::dynamic_extent, 7>(6));
+#endif
+
return true;
}