[libcxx-commits] [libcxx] [libc++][mdspan][NFC] Simplify `std::extents` implementation (PR #196819)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu May 14 22:08:05 PDT 2026
https://github.com/eiytoq updated https://github.com/llvm/llvm-project/pull/196819
>From 231249c9b5763a77055ce9b771eef8a695ac4d84 Mon Sep 17 00:00:00 2001
From: eiytoq <eiytoq at outlook.com>
Date: Mon, 11 May 2026 00:41:54 +0800
Subject: [PATCH] [libc++][mdspan][NFC] Simplify std::extents implementation
---
libcxx/include/__mdspan/extents.h | 61 +++++++++----------------------
1 file changed, 18 insertions(+), 43 deletions(-)
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index 379c762ace3ed..52c32f5052142 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -49,25 +49,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
namespace __mdspan_detail {
-
-// ------------------------------------------------------------------
-// ------------ __static_array --------------------------------------
-// ------------------------------------------------------------------
-// array like class which provides an array of static values with get
-template <class _Tp, _Tp... _Values>
-struct __static_array {
- static constexpr array<_Tp, sizeof...(_Values)> __array = {_Values...};
-
-public:
- _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Values); }
- _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get(size_t __index) noexcept { return __array[__index]; }
-
- template <size_t _Index>
- _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get() {
- return __get(_Index);
- }
-};
-
// ------------------------------------------------------------------
// ------------ __possibly_empty_array -----------------------------
// ------------------------------------------------------------------
@@ -120,35 +101,28 @@ struct __static_partial_sums {
// array like class which has a mix of static and runtime values but
// only stores the runtime values.
// The type of the static and the runtime values can be different.
-// The position of a dynamic value is indicated through a tag value.
-template <class _TDynamic, class _TStatic, _TStatic _DynTag, _TStatic... _Values>
+// The position of a dynamic value is indicated by dynamic_extent.
+template <class _TDynamic, class _TStatic, _TStatic... _Values>
struct __maybe_static_array {
- static_assert(is_convertible<_TStatic, _TDynamic>::value,
+ static_assert(is_convertible_v<_TStatic, _TDynamic>,
"__maybe_static_array: _TStatic must be convertible to _TDynamic");
- static_assert(is_convertible<_TDynamic, _TStatic>::value,
+ static_assert(is_convertible_v<_TDynamic, _TStatic>,
"__maybe_static_array: _TDynamic must be convertible to _TStatic");
private:
// Static values member
static constexpr size_t __size_ = sizeof...(_Values);
- static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0);
- using _StaticValues _LIBCPP_NODEBUG = __static_array<_TStatic, _Values...>;
+ static constexpr size_t __size_dynamic_ = ((_Values == dynamic_extent) + ... + 0);
using _DynamicValues _LIBCPP_NODEBUG = __possibly_empty_array<_TDynamic, __size_dynamic_>;
- // Dynamic values member
+ static constexpr array<_TStatic, sizeof...(_Values)> __static_values_ = {_Values...};
_LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_;
// static mapping of indices to the position in the dynamic values array
- using _DynamicIdxMap _LIBCPP_NODEBUG = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>;
-
- template <size_t... _Indices>
- _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<_Indices...>) noexcept {
- return _DynamicValues{((void)_Indices, 0)...};
- }
+ using _DynamicIdxMap _LIBCPP_NODEBUG = __static_partial_sums<static_cast<size_t>(_Values == dynamic_extent)...>;
public:
- _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept
- : __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {}
+ _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept : __dyn_vals_{} {}
// constructors from dynamic values only -- this covers the case for rank() == 0
template <class... _DynVals>
@@ -172,8 +146,8 @@ struct __maybe_static_array {
static_assert(sizeof...(_DynVals) == __size_, "Invalid number of values.");
_TDynamic __values[__size_] = {static_cast<_TDynamic>(__vals)...};
for (size_t __i = 0; __i < __size_; __i++) {
- _TStatic __static_val = _StaticValues::__get(__i);
- if (__static_val == _DynTag) {
+ _TStatic __static_val = __static_values_[__i];
+ if (__static_val == dynamic_extent) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
} else
// Not catching this could lead to out of bounds errors later
@@ -191,8 +165,8 @@ struct __maybe_static_array {
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) {
static_assert(_Size == __size_ || __size_ == dynamic_extent);
for (size_t __i = 0; __i < __size_; __i++) {
- _TStatic __static_val = _StaticValues::__get(__i);
- if (__static_val == _DynTag) {
+ _TStatic __static_val = __static_values_[__i];
+ if (__static_val == dynamic_extent) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
} else
// Not catching this could lead to out of bounds errors later
@@ -208,13 +182,15 @@ struct __maybe_static_array {
// access functions
_LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
- return _StaticValues::__get(__i);
+ return __static_values_[__i];
}
_LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
- _TStatic __static_val = _StaticValues::__get(__i);
- return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val);
+ _TStatic __static_val = __static_values_[__i];
+ return __static_val == dynamic_extent
+ ? __dyn_vals_[_DynamicIdxMap::__get(__i)]
+ : static_cast<_TDynamic>(__static_val);
}
_LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
@@ -296,8 +272,7 @@ class extents {
static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0);
// internal storage type using __maybe_static_array
- using _Values _LIBCPP_NODEBUG =
- __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>;
+ using _Values _LIBCPP_NODEBUG = __mdspan_detail::__maybe_static_array<_IndexType, size_t, _Extents...>;
[[no_unique_address]] _Values __vals_;
public:
More information about the libcxx-commits
mailing list