<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
StrongZero.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2017-2021, University of Tennessee. All rights reserved.
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_BASE_STRONGZERO_HH
12#define TLAPACK_BASE_STRONGZERO_HH
13
14#include <cassert>
15#include <cstdint>
16#include <limits>
17
19
20namespace tlapack {
21
43struct StrongZero {
44 // Constructors
45
46 constexpr StrongZero() {}
47
48 template <typename T>
49 constexpr StrongZero(const T& x) noexcept
50 {
51 assert(x == T(0));
52 }
53
54 template <typename T, typename U>
55 constexpr StrongZero(const T& x, const U& y) noexcept
56 {
57 assert(x == T(0));
58 assert(y == U(0));
59 }
60
61 // Conversion operators
62
63 template <typename T>
64 explicit constexpr operator T() const noexcept
65 {
66 return T(0);
67 }
68
69 // Assignment operators
70
71 template <typename T>
72 friend constexpr T& operator+=(T& lhs, StrongZero) noexcept
73 {
74 return lhs;
75 }
76
77 template <typename T>
78 friend constexpr T& operator-=(T& lhs, StrongZero) noexcept
79 {
80 return lhs;
81 }
82
83 template <typename T>
84 friend constexpr T& operator*=(T& lhs, StrongZero) noexcept
85 {
86 return (lhs = T(0));
87 }
88
89 template <typename T>
90 friend constexpr T& operator/=(T& lhs, StrongZero) noexcept
91 {
92 return (lhs = std::numeric_limits<T>::infinity());
93 }
94
95 // Arithmetic operators
96
97 friend constexpr StrongZero operator+(StrongZero, StrongZero) noexcept
98 {
99 return StrongZero();
100 }
101
102 template <typename T>
103 friend constexpr T operator+(StrongZero, const T& rhs) noexcept
104 {
105 return rhs;
106 }
107
108 template <typename T>
109 friend constexpr T operator+(const T& lhs, StrongZero) noexcept
110 {
111 return lhs;
112 }
113
114 friend constexpr StrongZero operator-(StrongZero, StrongZero) noexcept
115 {
116 return StrongZero();
117 }
118
119 template <typename T>
120 friend constexpr T operator-(StrongZero, const T& rhs) noexcept
121 {
122 return -rhs;
123 }
124
125 template <typename T>
126 friend constexpr T operator-(const T& lhs, StrongZero) noexcept
127 {
128 return lhs;
129 }
130
131 friend constexpr StrongZero operator*(StrongZero, StrongZero) noexcept
132 {
133 return StrongZero();
134 }
135
136 template <typename T>
137 friend constexpr StrongZero operator*(StrongZero, const T&) noexcept
138 {
139 return StrongZero();
140 }
141
142 template <typename T>
143 friend constexpr StrongZero operator*(const T&, StrongZero) noexcept
144 {
145 return StrongZero();
146 }
147
148 friend constexpr float operator/(StrongZero, StrongZero) noexcept
149 {
150 return std::numeric_limits<float>::quiet_NaN();
151 }
152
153 template <typename T>
154 friend constexpr StrongZero operator/(StrongZero, const T&) noexcept
155 {
156 return StrongZero();
157 }
158
159 template <typename T>
160 friend constexpr T operator/(const T&, StrongZero) noexcept
161 {
162 return std::numeric_limits<T>::infinity();
163 }
164
165 // Change of sign
166
167 constexpr StrongZero operator-() const noexcept { return StrongZero(); }
168
169 // Comparison operators
170
171 constexpr bool operator==(StrongZero) const noexcept { return true; }
172 constexpr bool operator!=(StrongZero) const noexcept { return false; }
173 constexpr bool operator>(StrongZero) const noexcept { return false; }
174 constexpr bool operator<(StrongZero) const noexcept { return false; }
175 constexpr bool operator>=(StrongZero) const noexcept { return true; }
176 constexpr bool operator<=(StrongZero) const noexcept { return true; }
177 friend constexpr bool isinf(StrongZero) noexcept { return false; }
178 friend constexpr bool isnan(StrongZero) noexcept { return false; }
179
180 // Math functions
181
182 friend constexpr StrongZero abs(StrongZero) noexcept
183 {
184 return StrongZero();
185 }
186 friend constexpr StrongZero sqrt(StrongZero) noexcept
187 {
188 return StrongZero();
189 }
190 friend constexpr int pow(int, StrongZero) noexcept { return 1; }
191 friend constexpr float log2(StrongZero) noexcept
192 {
193 return -std::numeric_limits<float>::infinity();
194 }
195 friend constexpr StrongZero ceil(StrongZero) noexcept
196 {
197 return StrongZero();
198 }
199 friend constexpr StrongZero floor(StrongZero) noexcept
200 {
201 return StrongZero();
202 }
203};
204
205namespace traits {
206
207 // for either StrongZero, return the other type
208 template <typename T>
210
211 // for either StrongZero, return the other type
212 template <typename T>
214
215 // tlapack::real_type<StrongZero> is StrongZero
216 template <>
218 using type = StrongZero;
219 constexpr static bool is_real = true;
220 };
221
222 // for either StrongZero, return the other type
223 template <typename T>
226
227 // for either StrongZero, return the other type
228 template <typename T>
231
232 // tlapack::complex_type<StrongZero> is StrongZero
233 template <>
235 using type = StrongZero;
236 constexpr static bool is_complex = false;
237 };
238} // namespace traits
239
240} // namespace tlapack
241
242template <>
243struct std::numeric_limits<tlapack::StrongZero> {
244 static constexpr bool is_specialized = true;
245
246 static constexpr tlapack::StrongZero min() noexcept
247 {
248 return tlapack::StrongZero();
249 }
250 static constexpr tlapack::StrongZero max() noexcept
251 {
252 return tlapack::StrongZero();
253 }
254 static constexpr tlapack::StrongZero lowest() noexcept
255 {
256 return tlapack::StrongZero();
257 }
258 static constexpr tlapack::StrongZero epsilon() noexcept
259 {
260 return tlapack::StrongZero();
261 }
262 static constexpr tlapack::StrongZero round_error() noexcept
263 {
264 return tlapack::StrongZero();
265 }
266 static constexpr tlapack::StrongZero infinity() noexcept
267 {
268 return tlapack::StrongZero();
269 }
270 static constexpr tlapack::StrongZero quiet_NaN() noexcept
271 {
272 return tlapack::StrongZero();
273 }
274 static constexpr tlapack::StrongZero signaling_NaN() noexcept
275 {
276 return tlapack::StrongZero();
277 }
278 static constexpr tlapack::StrongZero denorm_min() noexcept
279 {
280 return tlapack::StrongZero();
281 }
282};
283
284#endif // TLAPACK_BASE_STRONGZERO_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
constexpr bool is_complex
True if T is a complex scalar type.
Definition scalar_type_traits.hpp:192
constexpr bool is_real
True if T is a real scalar type.
Definition scalar_type_traits.hpp:117
Strong zero type.
Definition StrongZero.hpp:43
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