_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __mdspan
{
+ consteval bool
+ __all_dynamic(std::span<const size_t> __extents)
+ {
+ for(auto __ext : __extents)
+ if (__ext != dynamic_extent)
+ return false;
+ return true;
+ }
+
template<array _Extents>
class _StaticExtents
{
static constexpr size_t _S_rank = _Extents.size();
- // For __r in [0, _S_rank], _S_dynamic_index[__r] is the number
+ // For __r in [0, _S_rank], _S_dynamic_index(__r) is the number
// of dynamic extents up to (and not including) __r.
//
// If __r is the index of a dynamic extent, then
// _S_dynamic_index[__r] is the index of that extent in
// _M_dyn_exts.
- static constexpr auto _S_dynamic_index = [] consteval
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return _S_dynamic_index_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_data = [] consteval
{
array<size_t, _S_rank+1> __ret;
size_t __dyn = 0;
return __ret;
}();
- static constexpr size_t _S_rank_dynamic = _S_dynamic_index[_S_rank];
+ static constexpr size_t _S_rank_dynamic = _S_dynamic_index(_S_rank);
- // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv[__r] is the
+ // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv(__r) is the
// index of the __r-th dynamic extent in _Extents.
- static constexpr auto _S_dynamic_index_inv = [] consteval
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __r) noexcept
+ { return _S_dynamic_index_inv_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_inv_data = [] consteval
{
array<size_t, _S_rank_dynamic> __ret;
for (size_t __i = 0, __r = 0; __i < _S_rank; ++__i)
{ return _Extents[__r]; }
};
+ template<array _Extents>
+ requires (__all_dynamic<_Extents>())
+ class _StaticExtents<_Extents>
+ {
+ public:
+ static constexpr size_t _S_rank = _Extents.size();
+
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return __r; }
+
+ static constexpr size_t _S_rank_dynamic = _S_rank;
+
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __k) noexcept
+ { return __k; }
+
+ static constexpr size_t
+ _S_static_extent(size_t) noexcept
+ { return dynamic_extent; }
+ };
+
template<typename _IndexType, array _Extents>
class _ExtentsStorage : public _StaticExtents<_Extents>
{
using _S_base::_S_rank_dynamic;
using _S_base::_S_dynamic_index;
using _S_base::_S_dynamic_index_inv;
+ using _S_base::_S_static_extent;
template<typename _OIndexType>
static constexpr _IndexType
{
auto __se = _Extents[__r];
if (__se == dynamic_extent)
- return _M_dyn_exts[_S_dynamic_index[__r]];
+ return _M_dyn_exts[_S_dynamic_index(__r)];
else
return __se;
}
{
size_t __di = __i;
if constexpr (_OtherRank != _S_rank_dynamic)
- __di = _S_dynamic_index_inv[__i];
+ __di = _S_dynamic_index_inv(__i);
_M_dyn_exts[__i] = _S_int_cast(__get_extent(__di));
}
}
_M_dynamic_extents(size_t __begin, size_t __end) const noexcept
requires (_Extents.size() > 0)
{
- return {_M_dyn_exts + _S_dynamic_index[__begin],
- _M_dyn_exts + _S_dynamic_index[__end]};
+ return {_M_dyn_exts + _S_dynamic_index(__begin),
+ _M_dyn_exts + _S_dynamic_index(__end)};
}
private:
static_assert(
(__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
"Extents must either be dynamic or representable as IndexType");
-
public:
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
return 1;
else if constexpr (__rank == 2)
return __r == 0 ? 1 : __exts.extent(0);
+ else if constexpr (__all_dynamic(__sta_exts))
+ return __extents_prod(__exts, 1, 0, __r);
else
{
size_t __sta_prod = __fwd_partial_prods<__sta_exts>[__r];
return 1;
else if constexpr (__rank == 2)
return __r == 0 ? __exts.extent(1) : 1;
+ else if constexpr (__all_dynamic(__sta_exts))
+ return __extents_prod(__exts, 1, __r + 1, __rank);
else
{
size_t __sta_prod = __rev_partial_prods<__sta_exts>[__r];