llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

[libc++] P2389R2: `dextents` Index Type Parameter

Open xiaoyang-sde opened this issue 1 year ago • 1 comments

Introduction

This patch implements P2389R2, which was adopted at the St. Louis meeting. It builds upon previous enhancements from P2299R3, which introduced deduction guides and the dextents alias template. The main problem addressed is the increased verbosity of dextents following the parameterization of index types in P2553R1. After considering and rejecting a breaking change, the paper proposes introducing a new template alias called dims, which simplifies the declaration of mdspan with dynamic extents while maintaining the option to customize the index type.

Reference

xiaoyang-sde avatar Jul 02 '24 08:07 xiaoyang-sde

@llvm/pr-subscribers-libcxx

Author: Xiaoyang Liu (xiaoyang-sde)

Changes

Introduction

This patch implements P2389R2, which was adopted at the St. Louis meeting. It builds upon previous enhancements from P2299R3, which introduced deduction guides and the dextents alias template. The main problem addressed is the increased verbosity of dextents following the parameterization of index types in P2553R1. After considering and rejecting a breaking change, the paper proposes introducing a new template alias called dims, which simplifies the declaration of mdspan with dynamic extents while maintaining the option to customize the index type.

Reference


Full diff: https://github.com/llvm/llvm-project/pull/97393.diff

9 Files Affected:

  • (modified) libcxx/docs/FeatureTestMacroTable.rst (+2)
  • (modified) libcxx/docs/ReleaseNotes/19.rst (+1)
  • (modified) libcxx/include/__mdspan/extents.h (+6)
  • (modified) libcxx/include/mdspan (+4)
  • (modified) libcxx/include/version (+3-1)
  • (added) libcxx/test/std/containers/views/mdspan/extents/dims.pass.cpp (+49)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp (+3-3)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp (+2-2)
  • (modified) libcxx/utils/generate_feature_test_macro_components.py (+1-1)
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 72f624fa746b4..c7cdb15a7c3e1 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -440,6 +440,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_linalg``                                       *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_mdspan``                                       ``202406L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_out_ptr``                                      *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ranges_concat``                                *unimplemented*
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index d30021b7eb234..9d36a16df74f6 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -53,6 +53,7 @@ Implemented Papers
 - P2713R1 - Escaping improvements in ``std::format``
 - P2231R1 - Missing ``constexpr`` in ``std::optional`` and ``std::variant``
 - P0019R8 - ``std::atomic_ref``
+- P2389R2 - ``dextents`` Index Type Parameter
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index fea0decd8c6af..27d05122a11f5 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -465,6 +465,12 @@ template <class... _IndexTypes>
 explicit extents(_IndexTypes...) -> extents<size_t, size_t(((void)sizeof(_IndexTypes), dynamic_extent))...>;
 #  endif
 
+#  if _LIBCPP_STD_VER >= 26
+// [mdspan.extents.dims], alias template `dims`
+template <size_t _Rank, class _IndexType = size_t>
+using dims = dextents<_IndexType, _Rank>;
+#  endif
+
 namespace __mdspan_detail {
 
 // Helper type traits for identifying a class as extents.
diff --git a/libcxx/include/mdspan b/libcxx/include/mdspan
index 8d443f4acd1dd..aa7ba278b1aa0 100644
--- a/libcxx/include/mdspan
+++ b/libcxx/include/mdspan
@@ -20,6 +20,10 @@ namespace std {
   template<class IndexType, size_t Rank>
     using dextents = see below;
 
+  // [mdspan.extents.dims], alias template dims
+  template<size_t Rank, class IndexType = size_t>
+    using dims = see below; // since C++26
+
   // [mdspan.layout], layout mapping
   struct layout_left;
   struct layout_right;
diff --git a/libcxx/include/version b/libcxx/include/version
index cac6eaa3b6e88..c8ea46127db82 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -156,7 +156,7 @@ __cpp_lib_make_unique                                   201304L <memory>
 __cpp_lib_map_try_emplace                               201411L <map>
 __cpp_lib_math_constants                                201907L <numbers>
 __cpp_lib_math_special_functions                        201603L <cmath>
-__cpp_lib_mdspan                                        202207L <mdspan>
+__cpp_lib_mdspan                                        202406L <mdspan>
 __cpp_lib_memory_resource                               201603L <memory_resource>
 __cpp_lib_move_iterator_concept                         202207L <iterator>
 __cpp_lib_move_only_function                            202110L <functional>
@@ -521,6 +521,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_hazard_pointer                       202306L
 // # define __cpp_lib_is_within_lifetime                   202306L
 // # define __cpp_lib_linalg                               202311L
+# undef __cpp_lib_mdspan
+# define __cpp_lib_mdspan                               202406L
 # undef  __cpp_lib_out_ptr
 // # define __cpp_lib_out_ptr                              202311L
 // # define __cpp_lib_ranges_concat                        202403L
diff --git a/libcxx/test/std/containers/views/mdspan/extents/dims.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/dims.pass.cpp
new file mode 100644
index 0000000000000..e74bc0e66fca1
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/extents/dims.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// template<size_t Rank, class IndexType = size_t>
+//     using dims = see below;
+//
+// Result: A type E that is a specialization of extents such that
+//         E::rank() == Rank && E::rank() == E::rank_dynamic() is true,
+//         and E::index_type denotes IndexType.
+
+#include <mdspan>
+#include <cstddef>
+
+#include "test_macros.h"
+
+template <class IndexType>
+void test_alias_template_dims() {
+  constexpr size_t D = std::dynamic_extent;
+  ASSERT_SAME_TYPE(std::dims<0, IndexType>, std::extents<IndexType>);
+  ASSERT_SAME_TYPE(std::dims<1, IndexType>, std::extents<IndexType, D>);
+  ASSERT_SAME_TYPE(std::dims<2, IndexType>, std::extents<IndexType, D, D>);
+  ASSERT_SAME_TYPE(std::dims<3, IndexType>, std::extents<IndexType, D, D, D>);
+  ASSERT_SAME_TYPE(std::dims<9, IndexType>, std::extents<IndexType, D, D, D, D, D, D, D, D, D>);
+}
+
+template <>
+void test_alias_template_dims<size_t>() {
+  constexpr size_t D = std::dynamic_extent;
+  ASSERT_SAME_TYPE(std::dims<0>, std::extents<size_t>);
+  ASSERT_SAME_TYPE(std::dims<1>, std::extents<size_t, D>);
+  ASSERT_SAME_TYPE(std::dims<2>, std::extents<size_t, D, D>);
+  ASSERT_SAME_TYPE(std::dims<3>, std::extents<size_t, D, D, D>);
+  ASSERT_SAME_TYPE(std::dims<9>, std::extents<size_t, D, D, D, D, D, D, D, D, D>);
+}
+
+int main(int, char**) {
+  test_alias_template_dims<int>();
+  test_alias_template_dims<unsigned int>();
+  test_alias_template_dims<size_t>();
+  return 0;
+}
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
index 4ef3382306421..bd92562d31186 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
@@ -17,7 +17,7 @@
 
 /*  Constant                         Value
     __cpp_lib_freestanding_mdspan    202311L [C++26]
-    __cpp_lib_mdspan                 202207L [C++23]
+    __cpp_lib_mdspan                 202406L [C++26]
     __cpp_lib_submdspan              202306L [C++26]
 */
 
@@ -115,8 +115,8 @@
 # ifndef __cpp_lib_mdspan
 #   error "__cpp_lib_mdspan should be defined in c++26"
 # endif
-# if __cpp_lib_mdspan != 202207L
-#   error "__cpp_lib_mdspan should have the value 202207L in c++26"
+# if __cpp_lib_mdspan != 202406L
+#   error "__cpp_lib_mdspan should have the value 202406L in c++26"
 # endif
 
 # if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 32ed30e21cbbe..2a72ce97c1fbc 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -143,7 +143,7 @@
     __cpp_lib_map_try_emplace                               201411L [C++17]
     __cpp_lib_math_constants                                201907L [C++20]
     __cpp_lib_math_special_functions                        201603L [C++17]
-    __cpp_lib_mdspan                                        202207L [C++23]
+    __cpp_lib_mdspan                                        202406L [C++26]
     __cpp_lib_memory_resource                               201603L [C++17]
     __cpp_lib_modules                                       202207L [C++23]
     __cpp_lib_move_iterator_concept                         202207L [C++20]
@@ -7160,7 +7160,7 @@
 # ifndef __cpp_lib_mdspan
 #   error "__cpp_lib_mdspan should be defined in c++26"
 # endif
-# if __cpp_lib_mdspan != 202207L
+# if __cpp_lib_mdspan != 202406L
 #   error "__cpp_lib_mdspan should have the value 202207L in c++26"
 # endif
 
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index fe5bab05195a3..89cba7169e94b 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -848,7 +848,7 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_mdspan",
-            "values": {"c++23": 202207},
+            "values": {"c++23": 202207, "c++26": 202406},
             "headers": ["mdspan"],
         },
         {

llvmbot avatar Jul 02 '24 08:07 llvmbot

I've just committed https://github.com/llvm/llvm-project/pull/97951 can you rebase your patch on main and update the status page for this patch.

mordante avatar Jul 08 '24 17:07 mordante

Rebased and updated the status page. This can be merged once the CI is green.

ldionne avatar Jul 09 '24 18:07 ldionne

:white_check_mark: With the latest revision this PR passed the Python code formatter.

github-actions[bot] avatar Jul 09 '24 18:07 github-actions[bot]