1#[cfg(feature = "decimal")]
2use decimal::d128;
3use std::cmp::{Ordering, PartialOrd};
4
5pub trait MeetSemilattice: Sized {
7 fn meet(&self, other: &Self) -> Self;
9}
10
11pub trait JoinSemilattice: Sized {
13 fn join(&self, other: &Self) -> Self;
15}
16
17pub trait Lattice: MeetSemilattice + JoinSemilattice + PartialOrd {
19 #[inline]
21 fn meet_join(&self, other: &Self) -> (Self, Self) {
22 (self.meet(other), self.join(other))
23 }
24
25 #[inline]
27 fn partial_min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
28 if let Some(ord) = self.partial_cmp(other) {
29 match ord {
30 Ordering::Greater => Some(other),
31 _ => Some(self),
32 }
33 } else {
34 None
35 }
36 }
37
38 #[inline]
40 fn partial_max<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
41 if let Some(ord) = self.partial_cmp(other) {
42 match ord {
43 Ordering::Less => Some(other),
44 _ => Some(self),
45 }
46 } else {
47 None
48 }
49 }
50
51 #[inline]
53 fn partial_sort2<'a>(&'a self, other: &'a Self) -> Option<(&'a Self, &'a Self)> {
54 if let Some(ord) = self.partial_cmp(other) {
55 match ord {
56 Ordering::Less => Some((self, other)),
57 _ => Some((other, self)),
58 }
59 } else {
60 None
61 }
62 }
63
64 #[inline]
67 fn partial_clamp<'a>(&'a self, min: &'a Self, max: &'a Self) -> Option<&'a Self> {
68 if let (Some(cmp_min), Some(cmp_max)) = (self.partial_cmp(min), self.partial_cmp(max)) {
69 if cmp_min == Ordering::Less {
70 Some(min)
71 } else if cmp_max == Ordering::Greater {
72 Some(max)
73 } else {
74 Some(self)
75 }
76 } else {
77 None
78 }
79 }
80}
81
82macro_rules! impl_lattice(
83 ($($T:ident),*) => {$(
84 impl MeetSemilattice for $T {
85 #[inline]
86 fn meet(&self, other: &Self) -> Self {
87 if *self <= *other {
88 *self
89 }
90 else {
91 *other
92 }
93 }
94 }
95
96 impl JoinSemilattice for $T {
97 #[inline]
98 fn join(&self, other: &Self) -> Self {
99 if *self >= *other {
100 *self
101 }
102 else {
103 *other
104 }
105 }
106 }
107
108 impl Lattice for $T {
109 #[inline]
110 fn meet_join(&self, other: &Self) -> (Self, Self) {
111 if *self >= *other {
112 (*other, *self)
113 }
114 else {
115 (*self, *other)
116 }
117 }
118 }
119 )*}
120);
121
122impl_lattice!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64);
123#[cfg(feature = "decimal")]
124impl_lattice!(d128);
125
126impl<N: MeetSemilattice> MeetSemilattice for num_complex::Complex<N> {
127 #[inline]
128 fn meet(&self, other: &Self) -> Self {
129 Self {
130 re: self.re.meet(&other.re),
131 im: self.im.meet(&other.im),
132 }
133 }
134}
135
136impl<N: JoinSemilattice> JoinSemilattice for num_complex::Complex<N> {
137 #[inline]
138 fn join(&self, other: &Self) -> Self {
139 Self {
140 re: self.re.join(&other.re),
141 im: self.im.join(&other.im),
142 }
143 }
144}