<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
scalar_type_traits.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
5//
6// This file is part of <T>LAPACK.
7// <T>LAPACK is free software: you can redistribute it and/or modify it under
8// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
9
10#ifndef TLAPACK_SCALAR_TRAITS_HH
11#define TLAPACK_SCALAR_TRAITS_HH
12
13#include <complex>
14#include <type_traits>
15
16namespace tlapack {
17
18// C++ standard utils:
19using std::enable_if_t;
20
21// -----------------------------------------------------------------------------
22// for any combination of types, determine associated real, scalar,
23// and complex types.
24//
25// real_type< float > is float
26// real_type< float, double, complex<float> > is double
27//
28// scalar_type< float > is float
29// scalar_type< float, complex<float> > is complex<float>
30// scalar_type< float, double, complex<float> > is complex<double>
31//
32// complex_type< float > is complex<float>
33// complex_type< float, double > is complex<double>
34// complex_type< float, double, complex<float> > is complex<double>
35//
36// Adds promotion of complex types based on the common type of the associated
37// real types. This fixes various cases:
38//
39// std::std::common_type_t< double, complex<float> > is complex<float> (wrong)
40// scalar_type< double, complex<float> > is complex<double> (right)
41//
42// std::std::common_type_t< int, complex<long> > is not defined (compile error)
43// scalar_type< int, complex<long> > is complex<long> (right)
44
45// Real type traits
46namespace traits {
70 template <typename... Types>
72
73 // Traits for one non-const non-complex std arithmetic type
74 template <typename T>
76 T,
77 enable_if_t<std::is_arithmetic_v<T> && !std::is_const_v<T>, int>> {
78 using type = typename std::decay<T>::type;
79 constexpr static bool is_real = true;
80 };
81
82 // Traits for a std complex type (strip complex)
83 template <typename T>
84 struct real_type_traits<std::complex<T>, int> {
85 using type = typename real_type_traits<T, int>::type;
86 constexpr static bool is_real = false;
87 };
88
89 // Traits for a const type (strip const)
90 template <typename T>
91 struct real_type_traits<const T, int> : public real_type_traits<T, int> {};
92
93 // Pointers and references don't have a real type
94 template <typename T>
96 T,
97 enable_if_t<std::is_pointer_v<T> || std::is_reference_v<T>, int>> {
98 using type = void;
99 constexpr static bool is_real = false;
100 };
101
102 // Deduction for two or more types
103 template <typename T1, typename T2, typename... Types>
105 using type =
106 std::common_type_t<typename real_type_traits<T1, int>::type,
107 typename real_type_traits<T2, Types...>::type>;
108 };
109} // namespace traits
110
112template <typename... Types>
113using real_type = typename traits::real_type_traits<Types..., int>::type;
114
116template <typename T>
118
119// Complex type traits
120namespace traits {
144 template <typename... Types>
146
147 // Traits for one non-const non-complex std arithmetic type
148 template <typename T>
150 T,
151 enable_if_t<std::is_arithmetic_v<T> && !std::is_const_v<T>, int>> {
152 using type = std::complex<real_type<T>>;
153 constexpr static bool is_complex = false;
154 };
155
156 // Traits for a std complex type
157 template <typename T>
158 struct complex_type_traits<std::complex<T>, int> {
159 using type = std::complex<real_type<T>>;
160 constexpr static bool is_complex = true;
161 };
162
163 // Traits for a const type (strip const)
164 template <typename T>
166 : public complex_type_traits<T, int> {};
167
168 // Pointers and references don't have a complex type
169 template <typename T>
171 T,
172 enable_if_t<std::is_pointer_v<T> || std::is_reference_v<T>, int>> {
173 using type = void;
174 constexpr static bool is_complex = false;
175 };
176
177 // for two or more types
178 template <typename T1, typename T2, typename... Types>
180 using type = typename complex_type_traits<
181 typename real_type_traits<T1, T2, Types...>::type,
182 int>::type;
183 };
184} // namespace traits
185
187template <typename... Types>
188using complex_type = typename traits::complex_type_traits<Types..., int>::type;
189
191template <typename T>
193
194namespace traits {
215 template <typename... Types>
217
218 // for one type
219 template <typename T>
220 struct scalar_type_traits<T, int> : scalar_type_traits<T, T, int> {};
221
222 // for two types, one is complex
223 template <typename T1, typename T2>
225 T1,
226 T2,
227 enable_if_t<is_complex<T1> || is_complex<T2>, int>> {
228 using type = complex_type<T1, T2>;
229 };
230
231 // for two types, neither is complex
232 template <typename T1, typename T2>
234 T2,
235 enable_if_t<is_real<T1> && is_real<T2>, int>> {
236 using type = real_type<T1, T2>;
237 };
238
239 // for three or more types
240 template <typename T1, typename T2, typename... Types>
242 using type = typename scalar_type_traits<
244 Types...>::type;
245 };
246} // namespace traits
247
249template <typename... Types>
250using scalar_type = typename traits::scalar_type_traits<Types..., int>::type;
251
252} // namespace tlapack
253
254#endif // TLAPACK_SCALAR_TRAITS_HH
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113
typename traits::scalar_type_traits< Types..., int >::type scalar_type
The common scalar type of the list of types.
Definition scalar_type_traits.hpp:250
constexpr bool is_complex
True if T is a complex scalar type.
Definition scalar_type_traits.hpp:192
typename traits::complex_type_traits< Types..., int >::type complex_type
The common complex type of the list of types.
Definition scalar_type_traits.hpp:188
constexpr bool is_real
True if T is a real scalar type.
Definition scalar_type_traits.hpp:117
Complex type traits for the list of types Types.
Definition scalar_type_traits.hpp:145
Real type traits for the list of types Types.
Definition scalar_type_traits.hpp:71
Common scalar type deduced from the list of types Types.
Definition scalar_type_traits.hpp:216