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