tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
integral_constant_like.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2024 Tobias Hienzsch
3
4#ifndef TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
5#define TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
6
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>
15
16namespace etl::detail {
17
18template <typename T>
19concept pair_like = true;
20
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>;
25
26template <typename T>
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)>
30 /* and etl::equality_comparable_with<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;
33
34template <typename T>
35[[nodiscard]] constexpr auto de_ice(T val) -> T
36{
37 return val;
38}
39
40template <integral_constant_like T>
41[[nodiscard]] constexpr auto de_ice(T /*unused*/)
42{
43 return T::value;
44}
45
46template <etl::size_t K>
47[[nodiscard]] constexpr auto nth_slice_specifier(auto first, auto... rest)
48{
49 if constexpr (K == 0) {
50 return first;
51 } else {
52 nth_slice_specifier<K - 1>(rest...);
53 }
54}
55
56template <typename IndexType, etl::size_t K, typename... SliceSpecifiers>
57[[nodiscard]] constexpr auto submdspan_first(SliceSpecifiers... slices) -> IndexType
58{
59 auto sk = nth_slice_specifier<K>(slices...);
60 using Sk = decltype(sk);
61
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));
68 } else {
69 return static_cast<IndexType>(0);
70 }
71}
72
73template <etl::size_t K, typename Extents, typename... SliceSpecifiers>
74[[nodiscard]] constexpr auto submdspan_last(Extents const& src, SliceSpecifiers... slices)
75{
76 auto sk = nth_slice_specifier<K>(slices...);
77 using Sk = decltype(sk);
78 using IndexType = typename Extents::index_type;
79
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));
86 } else {
87 return static_cast<IndexType>(src.extent(K));
88 }
89}
90
91// template <typename IndexType, size_t N, typename... SliceSpecifiers>
92// [[nodiscard]] constexpr auto src_indices(array<IndexType, N> const& indices, SliceSpecifiers...
93// slices)
94// -> array<IndexType, sizeof...(SliceSpecifiers)>
95// {
96// }
97
98} // namespace etl::detail
99
100#endif // TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
Definition adjacent_find.hpp:9