[libcxx-commits] [libcxx] [libc++] P3029R1: Better `mdspan`'s CTAD - `std::extents` (PR #89015)

Xiaoyang Liu via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 16 20:41:15 PDT 2024


https://github.com/xiaoyang-sde created https://github.com/llvm/llvm-project/pull/89015

## Abstract

This pull request implements an improvement introduced in [P3029R1](https://wg21.link/P3029R1) that was ignored in #87873. The proposed change suggests deducing static extents if `integral_constant`-like constants are passed to `std::extents`.

## Reference

- [P3029R1](https://wg21.link/P3029R1)
- [Draft C++ Standard: [mdspan.extents.cons]](https://eel.is/c++draft/mdspan.extents.cons)

>From 8f173c17a851f91c21458813a776d63b8db8e157 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Tue, 16 Apr 2024 23:34:51 -0400
Subject: [PATCH] [libc++] P3029R1: Better mdspan's CTAD - 'std::extents'

---
 libcxx/include/__mdspan/extents.h                   |  9 ++++++++-
 .../containers/views/mdspan/extents/ctad.pass.cpp   | 13 ++++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index f6bcd940ee6077..d5f4a96f9f0891 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 3f99d8a3b47a2e..9144bb6812e3cc 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;
 }
 



More information about the libcxx-commits mailing list