On Thu, Oct 2, 2025 at 11:29 AM 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]> > --- > LGTM. > 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 > >
