num_valid/functions/
max_min.rs1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::validation::{Native64RawRealStrictFinitePolicy, debug_validate};
4use duplicate::duplicate_item;
5
6pub trait Max: PartialOrd + Sized {
26 fn max<'a>(&'a self, other: &'a Self) -> &'a Self {
37 if self >= other { self } else { other }
38 }
39
40 fn max_by_value(self, other: Self) -> Self {
51 if self >= other { self } else { other }
52 }
53}
54
55pub trait Min: PartialOrd + Sized {
73 fn min<'a>(&'a self, other: &'a Self) -> &'a Self {
84 if self <= other { self } else { other }
85 }
86
87 fn min_by_value(self, other: Self) -> Self {
98 if self <= other { self } else { other }
99 }
100}
101
102#[duplicate_item(
105 trait_name func func_by_value implementation;
106 [Max] [max] [max_by_value] [if self >= other { self } else { other }];
107 [Min] [min] [min_by_value] [if self <= other { self } else { other }];
108)]
109impl trait_name for f64 {
111 fn func<'a>(&'a self, other: &'a Self) -> &'a Self {
112 debug_validate::<Native64RawRealStrictFinitePolicy>(self, "left");
114 debug_validate::<Native64RawRealStrictFinitePolicy>(other, "right");
115
116 implementation
117 }
118
119 fn func_by_value(self, other: Self) -> Self {
120 debug_validate::<Native64RawRealStrictFinitePolicy>(&self, "left");
122 debug_validate::<Native64RawRealStrictFinitePolicy>(&other, "right");
123
124 implementation
125 }
126}
127#[cfg(test)]
131mod tests {
132 use super::*;
133
134 mod max {
135 use super::*;
136
137 mod native64 {
138 use super::*;
139
140 #[test]
141 fn test_f64_max_valid() {
142 let a = 3.0;
143 let b = 5.0;
144 let expected_result = 5.0;
145 assert_eq!(Max::max(&a, &b), &expected_result);
146 assert_eq!(Max::max_by_value(a, b), expected_result);
147 }
148
149 #[test]
150 fn test_f64_max_equal_values() {
151 let a = 3.0;
152 let b = 3.0;
153 let expected_result = 3.0;
154 assert_eq!(Max::max(&a, &b), &expected_result);
155 assert_eq!(Max::max_by_value(a, b), expected_result);
156 }
157
158 #[test]
159 fn test_f64_max_negative_values() {
160 let a = -3.0;
161 let b = -5.0;
162 let expected_result = -3.0;
163 assert_eq!(Max::max(&a, &b), &expected_result);
164 assert_eq!(Max::max_by_value(a, b), expected_result);
165 }
166
167 #[test]
168 #[cfg(debug_assertions)]
169 #[should_panic(expected = "Debug validation of left value failed: Value is NaN")]
170 fn test_f64_max_nan_value() {
171 let a = f64::NAN;
172 let b = 5.0;
173 let _result = Max::max(&a, &b);
174 }
175
176 #[test]
177 #[cfg(debug_assertions)]
178 #[should_panic(expected = "Debug validation of right value failed: Value is NaN")]
179 fn test_f64_max_nan_other() {
180 let a = 3.0;
181 let b = f64::NAN;
182 let _result = Max::max(&a, &b);
183 }
184
185 #[test]
186 #[cfg(debug_assertions)]
187 #[should_panic(
188 expected = "Debug validation of left value failed: Value is positive infinity"
189 )]
190 fn test_f64_max_infinite_value() {
191 let a = f64::INFINITY;
192 let b = 5.0;
193 let _result = Max::max(&a, &b);
194 }
195
196 #[test]
197 #[cfg(debug_assertions)]
198 #[should_panic(
199 expected = "Debug validation of right value failed: Value is positive infinity"
200 )]
201 fn test_f64_max_infinite_other() {
202 let a = 3.0;
203 let b = f64::INFINITY;
204 let _result = Max::max(&a, &b);
205 }
206
207 #[test]
208 #[cfg(debug_assertions)]
209 #[should_panic(
210 expected = "Debug validation of left value failed: Value is negative infinity"
211 )]
212 fn test_f64_max_neg_infinite_value() {
213 let a = f64::NEG_INFINITY;
214 let b = 5.0;
215 let _result = Max::max(&a, &b);
216 }
217
218 #[test]
219 #[cfg(debug_assertions)]
220 #[should_panic(
221 expected = "Debug validation of right value failed: Value is negative infinity"
222 )]
223 fn test_f64_max_neg_infinite_other() {
224 let a = 3.0;
225 let b = f64::NEG_INFINITY;
226 let _result = Max::max(&a, &b);
227 }
228
229 #[test]
230 #[cfg(debug_assertions)]
231 #[should_panic(expected = "Debug validation of left value failed: Value is subnormal")]
232 fn test_f64_max_subnormal_value() {
233 let a = f64::MIN_POSITIVE / 2.0;
234 let b = 5.0;
235 let _result = Max::max(&a, &b);
236 }
237
238 #[test]
239 #[cfg(debug_assertions)]
240 #[should_panic(expected = "Debug validation of right value failed: Value is subnormal")]
241 fn test_f64_max_subnormal_other() {
242 let a = 3.0;
243 let b = f64::MIN_POSITIVE / 2.0;
244 let _result = Max::max(&a, &b);
245 }
246 }
247
248 mod native64_strict_finite {
249 use try_create::TryNew;
250
251 use super::*;
252 use crate::kernels::native64_validated::RealNative64StrictFinite;
253
254 #[test]
255 fn test_f64_max_validated() {
256 let a = RealNative64StrictFinite::try_new(3.0).unwrap();
257 let b = RealNative64StrictFinite::try_new(5.0).unwrap();
258 let expected_result = RealNative64StrictFinite::try_new(5.0).unwrap();
259 assert_eq!(Max::max(&a, &b), &expected_result);
260 assert_eq!(Max::max_by_value(a, b), expected_result);
261 }
262
263 #[test]
264 fn test_f64_max_validated_equal() {
265 let a = RealNative64StrictFinite::try_new(3.0).unwrap();
266 let b = RealNative64StrictFinite::try_new(3.0).unwrap();
267 let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
268 assert_eq!(Max::max(&a, &b), &expected_result);
269 assert_eq!(Max::max_by_value(a, b), expected_result);
270 }
271 }
272 }
273
274 mod min {
275 use super::*;
276
277 mod native64 {
278 use super::*;
279
280 #[test]
281 fn test_f64_min_valid() {
282 let a = 3.0;
283 let b = 5.0;
284 let expected_result = 3.0;
285 assert_eq!(Min::min(&a, &b), &expected_result);
286 assert_eq!(Min::min_by_value(a, b), expected_result);
287 }
288
289 #[test]
290 fn test_f64_min_equal_values() {
291 let a = 3.0;
292 let b = 3.0;
293 let expected_result = 3.0;
294 assert_eq!(Min::min(&a, &b), &expected_result);
295 assert_eq!(Min::min_by_value(a, b), expected_result);
296 }
297
298 #[test]
299 fn test_f64_min_negative_values() {
300 let a = -3.0;
301 let b = -5.0;
302 let expected_result = -5.0;
303 assert_eq!(Min::min(&a, &b), &expected_result);
304 assert_eq!(Min::min_by_value(a, b), expected_result);
305 }
306
307 #[test]
308 #[cfg(debug_assertions)]
309 #[should_panic(expected = "Debug validation of left value failed: Value is NaN")]
310 fn test_f64_min_nan_value() {
311 let a = f64::NAN;
312 let b = 5.0;
313 let _result = Min::min(&a, &b);
314 }
315
316 #[test]
317 #[cfg(debug_assertions)]
318 #[should_panic(expected = "Debug validation of right value failed: Value is NaN")]
319 fn test_f64_min_nan_other() {
320 let a = 3.0;
321 let b = f64::NAN;
322 let _result = Min::min(&a, &b);
323 }
324 }
325
326 mod native64_strict_finite {
327 use try_create::TryNew;
328
329 use super::*;
330 use crate::kernels::native64_validated::RealNative64StrictFinite;
331
332 #[test]
333 fn test_f64_min_validated() {
334 let a = RealNative64StrictFinite::try_new(3.0).unwrap();
335 let b = RealNative64StrictFinite::try_new(5.0).unwrap();
336 let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
337 assert_eq!(Min::min(&a, &b), &expected_result);
338 assert_eq!(Min::min_by_value(a, b), expected_result);
339 }
340
341 #[test]
342 fn test_f64_min_validated_equal() {
343 let a = RealNative64StrictFinite::try_new(3.0).unwrap();
344 let b = RealNative64StrictFinite::try_new(3.0).unwrap();
345 let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
346 assert_eq!(Min::min(&a, &b), &expected_result);
347 assert_eq!(Min::min_by_value(a, b), expected_result);
348 }
349 }
350 }
351}
352