1use std::cmp::Ordering;
2
3pub trait Min: PartialOrd {
4 fn min(self, other: Self) -> Self;
5}
6
7impl<T> Min for T
8where
9 T: PartialOrd,
10{
11 fn min(self, other: Self) -> Self {
12 match self.partial_cmp(&other) {
13 Some(Ordering::Less) | Some(Ordering::Equal) => self,
14 Some(Ordering::Greater) => other,
15 None => {
16 if self != self {
17 other
18 } else {
19 self
20 }
21 }
22 }
23 }
24}
25
26#[cfg(test)]
27mod test {
28 use super::Min;
29
30 #[test]
31 fn it_works() {
32 let three = 3i32;
33 let four = 4i32;
34 assert_eq!(Min::min(three, four), 3);
35 assert_eq!(Min::min(four, three), 3);
36 assert_eq!(Min::min(three, three), 3);
37 }
38
39 #[test]
40 fn pointer_identity() {
41 let three = std::rc::Rc::new(3);
42 let three_again = std::rc::Rc::new(3);
43 assert_eq!(*Min::min(&*three, &*three_again), 3);
44 assert!(std::ptr::eq(
45 Min::min(&*three, &*three_again),
46 std::cmp::Ord::min(&*three, &*three_again)
47 ));
48 assert!(std::ptr::eq(
49 Min::min(&*three_again, &*three),
50 std::cmp::Ord::min(&*three_again, &*three)
51 ));
52 }
53
54 #[test]
55 fn f32() {
56 let three = 3.0f32;
57 let four = 4.0;
58 assert_eq!(Min::min(three, four), f32::min(three, four));
59 assert_eq!(Min::min(four, three), f32::min(four, three));
60 assert_eq!(Min::min(three, three), f32::min(three, three));
61
62 let nan = std::f32::NAN;
63 assert_ne!(nan, nan); assert_eq!(Min::min(three, nan), f32::min(three, nan));
65 assert_eq!(Min::min(nan, three), f32::min(nan, three));
66 assert_eq!(Min::min(nan, nan).is_nan(), f32::min(nan, nan).is_nan());
67
68 let inf = std::f32::INFINITY;
69 assert_eq!(Min::min(three, inf), f32::min(three, inf));
70 assert_eq!(Min::min(inf, three), f32::min(inf, three));
71
72 let neg_inf = std::f32::NEG_INFINITY;
73 assert_eq!(Min::min(three, neg_inf), f32::min(three, neg_inf));
74 assert_eq!(Min::min(neg_inf, three), f32::min(neg_inf, three));
75 }
76}