4#ifndef TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
5#define TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
7#include <etl/_concepts/convertible_to.hpp>
8#include <etl/_cstddef/size_t.hpp>
9#include <etl/_mdspan/strided_slice.hpp>
10#include <etl/_type_traits/always_false.hpp>
11#include <etl/_type_traits/bool_constant.hpp>
12#include <etl/_type_traits/is_integral.hpp>
13#include <etl/_type_traits/is_same.hpp>
14#include <etl/_type_traits/remove_const.hpp>
16namespace etl::detail {
19concept pair_like =
true;
21template <
typename T,
typename IndexType>
22concept index_pair_like = pair_like<T>
23 and etl::convertible_to<etl::tuple_element_t<0, T>, IndexType>
24 and etl::convertible_to<etl::tuple_element_t<1, T>, IndexType>;
27concept integral_constant_like =
etl::is_integral_v<
decltype(T::value)>
28 and not etl::is_same_v<
bool,
etl::remove_const_t<
decltype(T::value)>>
29 and etl::convertible_to<T,
decltype(T::value)>
31 and etl::bool_constant<T() == T::value>::value
32 and etl::bool_constant<
static_cast<
decltype(T::value)>(T()) == T::value>::value;
35[[nodiscard]]
constexpr auto de_ice(T val) -> T
40template <integral_constant_like T>
41[[nodiscard]]
constexpr auto de_ice(T )
46template <
etl::size_t K>
47[[nodiscard]]
constexpr auto nth_slice_specifier(
auto first,
auto... rest)
49 if constexpr (K == 0) {
52 nth_slice_specifier<K - 1>(rest...);
56template <
typename IndexType,
etl::size_t K,
typename... SliceSpecifiers>
57[[nodiscard]]
constexpr auto submdspan_first(SliceSpecifiers... slices) -> IndexType
59 auto sk = nth_slice_specifier<K>(slices...);
60 using Sk =
decltype(sk);
62 if constexpr (
etl::convertible_to<Sk, IndexType>) {
63 return static_cast<IndexType>(sk);
64 }
else if constexpr (index_pair_like<Sk, IndexType>) {
65 return static_cast<IndexType>(get<0>(sk));
66 }
else if constexpr (is_strided_slice<Sk>) {
67 return static_cast<IndexType>(de_ice(sk.offset));
69 return static_cast<IndexType>(0);
73template <
etl::size_t K,
typename Extents,
typename... SliceSpecifiers>
74[[nodiscard]]
constexpr auto submdspan_last(Extents
const& src, SliceSpecifiers... slices)
76 auto sk = nth_slice_specifier<K>(slices...);
77 using Sk =
decltype(sk);
78 using IndexType =
typename Extents::index_type;
80 if constexpr (
etl::convertible_to<Sk, IndexType>) {
81 return static_cast<IndexType>(de_ice(sk)) + IndexType(1);
82 }
else if constexpr (index_pair_like<Sk, IndexType>) {
83 return static_cast<IndexType>(get<1>(sk));
84 }
else if constexpr (is_strided_slice<Sk>) {
85 return static_cast<IndexType>(de_ice(sk.offset) + de_ice(sk.extent));
87 return static_cast<IndexType>(src.extent(K));
Definition adjacent_find.hpp:9