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
>