4#ifndef TETL_MDSPAN_SUBMDSPAN_EXTENTS_HPP
5#define TETL_MDSPAN_SUBMDSPAN_EXTENTS_HPP
7#include <etl/_cstddef/size_t.hpp>
8#include <etl/_mdspan/extents.hpp>
9#include <etl/_mdspan/full_extent.hpp>
10#include <etl/_mdspan/integral_constant_like.hpp>
11#include <etl/_mdspan/strided_slice.hpp>
12#include <etl/_span/dynamic_extent.hpp>
13#include <etl/_tuple/tuple_element.hpp>
14#include <etl/_type_traits/always_false.hpp>
15#include <etl/_type_traits/is_convertible.hpp>
21template <
etl::size_t K,
typename Extent,
typename Sk>
22constexpr auto submdspan_static_extent()
24 using IndexT =
typename Extent::index_type;
28 return Extent::static_extent(Extent::rank() - K);
29 }
else if constexpr (index_pair_like<Sk, IndexT>) {
30 using FirstT =
etl::tuple_element_t<0, Sk>;
31 using SecondT =
etl::tuple_element_t<1, Sk>;
32 if constexpr (integral_constant_like<FirstT>
and integral_constant_like<SecondT>) {
33 return de_ice(
etl::tuple_element_t<1, Sk>()) - de_ice(
etl::tuple_element_t<0, Sk>());
35 }
else if constexpr (is_strided_slice<Sk>) {
36 using ExtT =
typename Sk::extent_type;
37 using StrideT =
typename Sk::stride_type;
38 if constexpr (integral_constant_like<ExtT>
and not integral_constant_like<StrideT>
and ExtT() == 0) {
40 }
else if constexpr (integral_constant_like<ExtT>
and integral_constant_like<StrideT>) {
41 return 1 + (de_ice(ExtT()) - 1) / de_ice(StrideT());
49template <
etl::size_t K,
typename Extents, size_t... NewExtents>
50struct submdspan_extents_builder {
51 template <
typename Slice,
typename... SlicesAndExtents>
52 static constexpr auto next(Extents
const& ext, Slice
const& , SlicesAndExtents... slicesAndExtents)
55 return submdspan_extents_builder<
58 Extents::static_extent(Extents::rank() - K),
60 >::next(ext, slicesAndExtents..., ext.extent(Extents::rank() - K));
61 }
else if constexpr (
etl::is_convertible_v<Slice,
etl::size_t>) {
62 return submdspan_extents_builder<K - 1, Extents, NewExtents...>::next(ext, slicesAndExtents...);
63 }
else if constexpr (is_strided_slice<Slice>) {
64 static_assert(
etl::always_false<Slice>);
66 constexpr auto newStaticExt = submdspan_static_extent<K, Extents, Slice>();
67 return submdspan_extents_builder<K - 1, Extents, newStaticExt, NewExtents...>::next(
75template <
typename Extents, size_t... NewStaticExtents>
76struct submdspan_extents_builder<0, Extents, NewStaticExtents...> {
77 template <
typename... NewExtents>
78 static constexpr auto next(Extents
const& , NewExtents... newExts)
80 return etl::
extents<
typename Extents::index_type, NewStaticExtents...>(newExts...);
86template <
typename IndexT,
etl::size_t... Extents,
typename... SliceSpecifiers>
88 requires(
sizeof...(slices) ==
etl::
extents<IndexT, Extents...>::rank())
90 using ext_t =
etl::
extents<IndexT, Extents...>;
91 return detail::submdspan_extents_builder<ext_t::rank(), ext_t>::next(ext, slices...);
constexpr auto dynamic_extent
etl::dynamic_extent is a constant of type etl::size_t that is used to differentiate etl::span of stat...
Definition dynamic_extent.hpp:15
Definition adjacent_find.hpp:9
constexpr auto submdspan_extents(etl::extents< IndexT, Extents... > const &ext, SliceSpecifiers... slices)
Definition submdspan_extents.hpp:87
Definition extents.hpp:23
Definition full_extent.hpp:10