From 4fd3a9ac56bc751916406998c08e96c9f71d637b Mon Sep 17 00:00:00 2001 From: Christian Trott Date: Fri, 31 May 2024 15:44:51 -0600 Subject: [PATCH] Avoid use of zero-length carray --- .../__p0009_bits/layout_stride.hpp | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/include/experimental/__p0009_bits/layout_stride.hpp b/include/experimental/__p0009_bits/layout_stride.hpp index 53e47739..ded3156e 100644 --- a/include/experimental/__p0009_bits/layout_stride.hpp +++ b/include/experimental/__p0009_bits/layout_stride.hpp @@ -202,9 +202,17 @@ struct layout_stride { return __strides_storage_t{static_cast(s[Idxs])...}; } - template + MDSPAN_TEMPLATE_REQUIRES( + class IntegralType, + // The is_convertible condition is added to make sfinae valid + // the extents_type::rank() > 0 is added to avoid use of non-standard zero length c-array + (std::is_convertible::value && (extents_type::rank() > 0)) + ) MDSPAN_INLINE_FUNCTION - static constexpr const __strides_storage_t fill_strides(mdspan_non_standard_tag, const IntegralType (&s)[extents_type::rank()]) { + // despite the requirement some compilers still complain about zero length array during parsing + // making it length 1 now, but since the thing can't be instantiated due to requirement the actual + // instantiation of strides_storage will not fail despite mismatching length + static constexpr const __strides_storage_t fill_strides(mdspan_non_standard_tag, const IntegralType (&s)[extents_type::rank()>0?extents_type::rank():1]) { return __strides_storage_t{static_cast(s[Idxs])...}; } @@ -325,7 +333,8 @@ struct layout_stride { // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t&, typename Extents::index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t&) + _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t&) && + (Extents::rank() > 0) ) ) MDSPAN_INLINE_FUNCTION @@ -333,7 +342,10 @@ struct layout_stride { mapping( mdspan_non_standard_tag, extents_type const& e, - IntegralTypes (&s)[extents_type::rank()] + // despite the requirement some compilers still complain about zero length array during parsing + // making it length 1 now, but since the thing can't be instantiated due to requirement the actual + // instantiation of strides_storage will not fail despite mismatching length + IntegralTypes (&s)[extents_type::rank()>0?extents_type::rank():1] ) noexcept #if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : __members{