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