tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch
3
4#ifndef TETL_LINALG_CONCEPTS_HPP
5#define TETL_LINALG_CONCEPTS_HPP
6
7#include <etl/_complex/abs.hpp>
8#include <etl/_complex/complex.hpp>
9#include <etl/_complex/conj.hpp>
10#include <etl/_complex/imag.hpp>
11#include <etl/_complex/real.hpp>
12#include <etl/_concepts/same_as.hpp>
13#include <etl/_concepts/unsigned_integral.hpp>
14#include <etl/_math/abs.hpp>
15#include <etl/_mdspan/layout.hpp>
16#include <etl/_mdspan/layout_left.hpp>
17#include <etl/_mdspan/layout_right.hpp>
18#include <etl/_mdspan/mdspan.hpp>
19#include <etl/_numeric/abs.hpp>
20#include <etl/_type_traits/always_false.hpp>
21#include <etl/_type_traits/bool_constant.hpp>
22#include <etl/_type_traits/common_type.hpp>
23#include <etl/_type_traits/declval.hpp>
24#include <etl/_type_traits/is_arithmetic.hpp>
25#include <etl/_type_traits/is_same.hpp>
26#include <etl/_type_traits/remove_const.hpp>
27
28namespace etl::linalg::detail {
29
30template <typename T>
31struct is_mdspan : false_type { };
32
33template <typename T, typename Extents, typename Layout, typename Accessor>
34struct is_mdspan<mdspan<T, Extents, Layout, Accessor>> : true_type { };
35
36template <typename... Ts>
37using common_size_type_t = common_type_t<typename Ts::size_type...>;
38
39namespace linalg_adl_checks {
40
41using etl::abs;
42using etl::conj;
43using etl::imag;
44using etl::real;
45
46template <typename T>
47auto abs(T const&) -> T = delete;
48template <typename T>
49auto conj(T const&) -> T = delete;
50template <typename T>
51auto real(T const&) -> T = delete;
52template <typename T>
53auto imag(T const&) -> T = delete;
54
55template <typename T>
56concept has_abs = requires { abs(declval<T>()); };
57
58template <typename T>
59concept has_conj = requires { conj(declval<T>()); };
60
61template <typename T>
62concept has_real = requires { real(declval<T>()); };
63
64template <typename T>
65concept has_imag = requires { imag(declval<T>()); };
66
67} // namespace linalg_adl_checks
68
69template <typename T>
70concept has_adl_abs = linalg_adl_checks::has_abs<T>;
71
72template <typename T>
73concept has_adl_conj = linalg_adl_checks::has_conj<T>;
74
75template <typename T>
76concept has_adl_real = linalg_adl_checks::has_real<T>;
77
78template <typename T>
79concept has_adl_imag = linalg_adl_checks::has_imag<T>;
80
81inline constexpr auto abs_if_needed = []<typename T>(T const& val) {
82 if constexpr (unsigned_integral<T>) {
83 return val;
84 } else if constexpr (is_arithmetic_v<T>) {
85 return etl::abs(val);
86 } else if constexpr (has_adl_abs<T>) {
87 return abs(val);
88 } else {
89 static_assert(always_false<T>);
90 }
91};
92
93inline constexpr auto conj_if_needed = []<typename T>(T const& val) {
94 if constexpr (not is_arithmetic_v<T> and has_adl_conj<T>) {
95 return conj(val);
96 } else {
97 return val;
98 }
99};
100
101inline constexpr auto real_if_needed = []<typename T>(T const& val) {
102 if constexpr (not is_arithmetic_v<T> and has_adl_real<T>) {
103 return real(val);
104 } else {
105 return val;
106 }
107};
108
109inline constexpr auto imag_if_needed = []<typename T>(T const& val) {
110 if constexpr (not is_arithmetic_v<T> and has_adl_imag<T>) {
111 return imag(val);
112 } else {
113 return T{};
114 }
115};
116
117} // namespace etl::linalg::detail
118
119namespace etl::linalg {
120
121/// \ingroup linalg
122template <typename T>
123concept in_vector = detail::is_mdspan<T>::value && T::rank() == 1;
124
125/// \ingroup linalg
126template <typename T>
127concept out_vector = detail::is_mdspan<T>::value
128 && T::rank() == 1
129 && same_as<remove_const_t<typename T::element_type>, typename T::element_type>
130 && T::is_always_unique();
131
132/// \ingroup linalg
133template <typename T>
134concept inout_vector = detail::is_mdspan<T>::value
135 && T::rank() == 1
136 && same_as<remove_const_t<typename T::element_type>, typename T::element_type>
137 && T::is_always_unique();
138
139/// \ingroup linalg
140template <typename T>
141concept in_matrix = detail::is_mdspan<T>::value && T::rank() == 2;
142
143/// \ingroup linalg
144template <typename T>
145concept out_matrix = detail::is_mdspan<T>::value
146 && T::rank() == 2
147 && is_same_v<remove_const_t<typename T::element_type>, typename T::element_type>
148 && T::is_always_unique();
149
150/// \ingroup linalg
151template <typename T>
152concept inout_matrix = detail::is_mdspan<T>::value
153 && T::rank() == 2
154 && is_same_v<remove_const_t<typename T::element_type>, typename T::element_type>
155 && T::is_always_unique();
156
157// template <typename T>
158// concept possibly_packed_inout_matrix =
159// detail::is_mdspan<T>::value && T::rank() == 2 &&
160// is_same_v<remove_const_t<typename T::element_type>,
161// typename T::element_type> &&
162// (T::is_always_unique() ||
163// is_same_v<typename T::layout_type, layout_blas_packed>);
164
165/// \ingroup linalg
166template <typename T>
167concept in_object = detail::is_mdspan<T>::value && (T::rank() == 1 || T::rank() == 2);
168
169/// \ingroup linalg
170template <typename T>
171concept out_object = detail::is_mdspan<T>::value
172 && (T::rank() == 1 || T::rank() == 2)
173 && is_same_v<remove_const_t<typename T::element_type>, typename T::element_type>
174 && T::is_always_unique();
175
176/// \ingroup linalg
177template <typename T>
178concept inout_object = detail::is_mdspan<T>::value
179 && (T::rank() == 1 || T::rank() == 2)
180 && is_same_v<remove_const_t<typename T::element_type>, typename T::element_type>
181 && T::is_always_unique();
182
183} // namespace etl::linalg
184
185#endif // TETL_LINALG_CONCEPTS_HPP
Definition accessor_conjugate.hpp:13
Definition adjacent_find.hpp:9
Definition mdspan.hpp:40