On Thu, 2 Oct 2025 at 10:28, Luc Grosheintz <[email protected]> wrote:
>
> Adds strided_slice as standardized in N5014. Also creates
> the internal feature testing macro for submdspan.
>
>         PR libstdc++/110352
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/version.def (submdspan): New internal macro.
>         * include/bits/version.h: Regenerate.
>         * include/std/mdspan (strided_slice): New class.
>         * src/c++23/std.cc.in (strided_slice): Add.
>         * testsuite/23_containers/mdspan/submdspan/strided_slice.cc: New test.
>         * testsuite/23_containers/mdspan/submdspan/strided_slice_neg.cc: New 
> test.
>
> Signed-off-by: Luc Grosheintz <[email protected]>
> ---

OK for trunk, thanks.

>  libstdc++-v3/include/bits/version.def         |  9 ++++
>  libstdc++-v3/include/bits/version.h           |  9 ++++
>  libstdc++-v3/include/std/mdspan               | 21 +++++++++
>  libstdc++-v3/src/c++23/std.cc.in              |  3 +-
>  .../mdspan/submdspan/strided_slice.cc         | 46 +++++++++++++++++++
>  .../mdspan/submdspan/strided_slice_neg.cc     | 19 ++++++++
>  6 files changed, 106 insertions(+), 1 deletion(-)
>  create mode 100644 
> libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
>  create mode 100644 
> libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice_neg.cc
>
> diff --git a/libstdc++-v3/include/bits/version.def 
> b/libstdc++-v3/include/bits/version.def
> index 9fe3ad2feda..7c91a18c686 100644
> --- a/libstdc++-v3/include/bits/version.def
> +++ b/libstdc++-v3/include/bits/version.def
> @@ -1075,6 +1075,15 @@ ftms = {
>    };
>  };
>
> +ftms = {
> +  name = submdspan;
> +  no_stdname = true; // TODO: change once complete
> +  values = {
> +    v = 1;
> +    cxxmin = 26;
> +  };
> +};
> +
>  ftms = {
>    name = ssize;
>    values = {
> diff --git a/libstdc++-v3/include/bits/version.h 
> b/libstdc++-v3/include/bits/version.h
> index d9bf5c8145a..044d756de19 100644
> --- a/libstdc++-v3/include/bits/version.h
> +++ b/libstdc++-v3/include/bits/version.h
> @@ -1202,6 +1202,15 @@
>  #endif /* !defined(__cpp_lib_padded_layouts) && 
> defined(__glibcxx_want_padded_layouts) */
>  #undef __glibcxx_want_padded_layouts
>
> +#if !defined(__cpp_lib_submdspan)
> +# if (__cplusplus >  202302L)
> +#  define __glibcxx_submdspan 1L
> +#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_submdspan)
> +#  endif
> +# endif
> +#endif /* !defined(__cpp_lib_submdspan) && defined(__glibcxx_want_submdspan) 
> */
> +#undef __glibcxx_want_submdspan
> +
>  #if !defined(__cpp_lib_ssize)
>  # if (__cplusplus >= 202002L)
>  #  define __glibcxx_ssize 201902L
> diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
> index 8efd168bcf0..4828806d817 100644
> --- a/libstdc++-v3/include/std/mdspan
> +++ b/libstdc++-v3/include/std/mdspan
> @@ -44,6 +44,7 @@
>
>  #define __glibcxx_want_mdspan
>  #define __glibcxx_want_aligned_accessor
> +#define __glibcxx_want_submdspan
>  #include <bits/version.h>
>
>  #ifdef __glibcxx_mdspan
> @@ -335,6 +336,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>        { return __exts._M_exts._M_dynamic_extents(__begin, __end); }
>    }
>
> +#if __glibcxx_submdspan
> +  template<typename _OffsetType, typename _ExtentType, typename _StrideType>
> +    struct strided_slice {
> +      static_assert(__is_standard_integer<_OffsetType>::value
> +       || __detail::__integral_constant_like<_OffsetType>);
> +      static_assert(__is_standard_integer<_ExtentType>::value
> +       || __detail::__integral_constant_like<_ExtentType>);
> +      static_assert(__is_standard_integer<_StrideType>::value
> +       || __detail::__integral_constant_like<_StrideType>);
> +
> +      using offset_type = _OffsetType;
> +      using extent_type = _ExtentType;
> +      using stride_type = _StrideType;
> +
> +      [[no_unique_address]] offset_type offset{};
> +      [[no_unique_address]] extent_type extent{};
> +      [[no_unique_address]] stride_type stride{};
> +    };
> +#endif
> +
>    template<typename _IndexType, size_t... _Extents>
>      class extents
>      {
> diff --git a/libstdc++-v3/src/c++23/std.cc.in 
> b/libstdc++-v3/src/c++23/std.cc.in
> index c1b4e4c88b7..8da78fe955b 100644
> --- a/libstdc++-v3/src/c++23/std.cc.in
> +++ b/libstdc++-v3/src/c++23/std.cc.in
> @@ -1872,8 +1872,9 @@ export namespace std
>  #if __glibcxx_padded_layouts
>    using std::layout_left_padded;
>    using std::layout_right_padded;
> +  using strided_slice;
>  #endif
> -  // FIXME strided_slice, submdspan_mapping_result, full_extent_t, 
> full_extent,
> +  // FIXME submdspan_mapping_result, full_extent_t, full_extent,
>    // submdspan_extents, mdsubspan
>  }
>  #endif
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc 
> b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
> new file mode 100644
> index 00000000000..c43a8214321
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice.cc
> @@ -0,0 +1,46 @@
> +// { dg-do run { target c++26 } }
> +#include <mdspan>
> +
> +#include <cstdint>
> +#include <testsuite_hooks.h>
> +
> +constexpr void
> +check_strided_slice(auto s, auto offset, auto extent, auto stride)
> +{
> +  using slice_type = std::strided_slice<decltype(offset), decltype(extent),
> +                                       decltype(stride)>;
> +  static_assert(std::same_as<decltype(s), slice_type>);
> +  VERIFY(s.offset == offset);
> +  VERIFY(s.extent == extent);
> +  VERIFY(s.stride == stride);
> +}
> +
> +constexpr void
> +test_initializers(auto offset, auto extent, auto stride)
> +{
> +  auto check = [&](auto s)
> +  {
> +    check_strided_slice(s, offset, extent, stride);
> +  };
> +
> +  check(std::strided_slice{.offset=offset, .extent=extent, .stride=stride});
> +  check(std::strided_slice{offset, extent, stride});
> +  check(std::strided_slice(offset, extent, stride));
> +}
> +
> +constexpr bool
> +test_all()
> +{
> +  test_initializers(0, 1, 2);
> +  test_initializers(std::integral_constant<short, 0>{}, size_t{1}, 
> std::cw<2>);
> +  test_initializers(-1, 2, 2);
> +  return true;
> +}
> +
> +int
> +main()
> +{
> +  test_all();
> +  static_assert(test_all());
> +  return 0;
> +}
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice_neg.cc 
> b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice_neg.cc
> new file mode 100644
> index 00000000000..0f1d791d13a
> --- /dev/null
> +++ 
> b/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/strided_slice_neg.cc
> @@ -0,0 +1,19 @@
> +// { dg-do compile { target c++26 } }
> +#include <mdspan>
> +
> +#include <cstdint>
> +
> +template<typename OffsetType, typename ExtentType, typename StrideType>
> +  constexpr bool
> +  test_invalid()
> +  {
> +    auto s1 = std::strided_slice(OffsetType{}, ExtentType{}, StrideType{}); 
> // { dg-error "required from" }
> +    return true;
> +  }
> +
> +static_assert(test_invalid<double, int, int>()); // { dg-error "required 
> from" }
> +static_assert(test_invalid<int, double, int>()); // { dg-error "required 
> from" }
> +static_assert(test_invalid<int, int, double>()); // { dg-error "required 
> from" }
> +static_assert(test_invalid<double, double, double>()); // { dg-error 
> "required from" }
> +
> +// { dg-prune-output "static assertion failed" }
> --
> 2.50.1
>

Reply via email to