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 = //
23 pair_like<T> //
24 and etl::convertible_to<etl::tuple_element_t<0, T>, IndexType> //
25 and etl::convertible_to<etl::tuple_element_t<1, T>, IndexType> //
26 ;
27
28template <typename T>
29concept integral_constant_like = //
30 etl::is_integral_v<decltype(T::value)> //
31 and not etl::is_same_v<bool, etl::remove_const_t<decltype(T::value)>> //
32 and etl::convertible_to<T, decltype(T::value)> //
33 /* and etl::equality_comparable_with<T, decltype(T::value)> */ //
34 and etl::bool_constant<T() == T::value>::value //
35 and etl::bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value //
36 ;
37
38template <typename T>
39[[nodiscard]] constexpr auto de_ice(T val) -> T
40{
41 return val;
42}
43
44template <integral_constant_like T>
45[[nodiscard]] constexpr auto de_ice(T /*unused*/)
46{
47 return T::value;
48}
49
50template <etl::size_t K>
51[[nodiscard]] constexpr auto nth_slice_specifier(auto first, auto... rest)
52{
53 if constexpr (K == 0) {
54 return first;
55 } else {
56 nth_slice_specifier<K - 1>(rest...);
57 }
58}
59
60template <typename IndexType, etl::size_t K, typename... SliceSpecifiers>
61[[nodiscard]] constexpr auto submdspan_first(SliceSpecifiers... slices) -> IndexType
62{
63 auto sk = nth_slice_specifier<K>(slices...);
64 using Sk = decltype(sk);
65
66 if constexpr (etl::convertible_to<Sk, IndexType>) {
67 return static_cast<IndexType>(sk);
68 } else if constexpr (index_pair_like<Sk, IndexType>) {
69 return static_cast<IndexType>(get<0>(sk));
70 } else if constexpr (is_strided_slice<Sk>) {
71 return static_cast<IndexType>(de_ice(sk.offset));
72 } else {
73 return static_cast<IndexType>(0);
74 }
75}
76
77template <etl::size_t K, typename Extents, typename... SliceSpecifiers>
78[[nodiscard]] constexpr auto submdspan_last(Extents const& src, SliceSpecifiers... slices)
79{
80 auto sk = nth_slice_specifier<K>(slices...);
81 using Sk = decltype(sk);
82 using IndexType = typename Extents::index_type;
83
84 if constexpr (etl::convertible_to<Sk, IndexType>) {
85 return static_cast<IndexType>(de_ice(sk)) + IndexType(1);
86 } else if constexpr (index_pair_like<Sk, IndexType>) {
87 return static_cast<IndexType>(get<1>(sk));
88 } else if constexpr (is_strided_slice<Sk>) {
89 return static_cast<IndexType>(de_ice(sk.offset) + de_ice(sk.extent));
90 } else {
91 return static_cast<IndexType>(src.extent(K));
92 }
93}
94
95// template <typename IndexType, size_t N, typename... SliceSpecifiers>
96// [[nodiscard]] constexpr auto src_indices(array<IndexType, N> const& indices, SliceSpecifiers...
97// slices)
98// -> array<IndexType, sizeof...(SliceSpecifiers)>
99// {
100// }
101
102} // namespace etl::detail
103
104#endif // TETL_MDSPAN_INTEGRAL_CONSTANT_LIKE_HPP
Definition adjacent_find.hpp:9