1pub trait MinMax: Sized {
11 fn nan_min_lt(&self, other: &Self) -> bool;
15 fn nan_max_lt(&self, other: &Self) -> bool;
16
17 #[inline(always)]
19 fn min_propagate_nan(self, other: Self) -> Self {
20 if self.nan_min_lt(&other) {
21 self
22 } else {
23 other
24 }
25 }
26
27 #[inline(always)]
28 fn max_propagate_nan(self, other: Self) -> Self {
29 if self.nan_max_lt(&other) {
30 other
31 } else {
32 self
33 }
34 }
35
36 #[inline(always)]
37 fn min_ignore_nan(self, other: Self) -> Self {
38 if self.nan_max_lt(&other) {
39 self
40 } else {
41 other
42 }
43 }
44
45 #[inline(always)]
46 fn max_ignore_nan(self, other: Self) -> Self {
47 if self.nan_min_lt(&other) {
48 other
49 } else {
50 self
51 }
52 }
53}
54
55macro_rules! impl_trivial_min_max {
56 ($T: ty) => {
57 impl MinMax for $T {
58 #[inline(always)]
59 fn nan_min_lt(&self, other: &Self) -> bool {
60 self < other
61 }
62
63 #[inline(always)]
64 fn nan_max_lt(&self, other: &Self) -> bool {
65 self < other
66 }
67 }
68 };
69}
70
71impl_trivial_min_max!(bool);
74impl_trivial_min_max!(u8);
75impl_trivial_min_max!(u16);
76impl_trivial_min_max!(u32);
77impl_trivial_min_max!(u64);
78impl_trivial_min_max!(u128);
79impl_trivial_min_max!(usize);
80impl_trivial_min_max!(i8);
81impl_trivial_min_max!(i16);
82impl_trivial_min_max!(i32);
83impl_trivial_min_max!(i64);
84impl_trivial_min_max!(i128);
85impl_trivial_min_max!(isize);
86impl_trivial_min_max!(char);
87impl_trivial_min_max!(&str);
88impl_trivial_min_max!(&[u8]);
89impl_trivial_min_max!(String);
90
91macro_rules! impl_float_min_max {
92 ($T: ty) => {
93 impl MinMax for $T {
94 #[inline(always)]
95 fn nan_min_lt(&self, other: &Self) -> bool {
96 !(other.is_nan() | (self >= other))
97 }
98
99 #[inline(always)]
100 fn nan_max_lt(&self, other: &Self) -> bool {
101 !(self.is_nan() | (self >= other))
102 }
103
104 #[inline(always)]
105 fn min_ignore_nan(self, other: Self) -> Self {
106 <$T>::min(self, other)
107 }
108
109 #[inline(always)]
110 fn max_ignore_nan(self, other: Self) -> Self {
111 <$T>::max(self, other)
112 }
113
114 #[inline(always)]
115 fn min_propagate_nan(self, other: Self) -> Self {
116 if (self < other) | self.is_nan() {
117 self
118 } else {
119 other
120 }
121 }
122
123 #[inline(always)]
124 fn max_propagate_nan(self, other: Self) -> Self {
125 if (self > other) | self.is_nan() {
126 self
127 } else {
128 other
129 }
130 }
131 }
132 };
133}
134
135impl_float_min_max!(f32);
136impl_float_min_max!(f64);