ascent_base/lattice/
dual.rs

1use std::cmp::Ordering;
2use std::fmt::{Debug, Display, Formatter};
3use std::ops::Deref;
4
5use super::BoundedLattice;
6use crate::Lattice;
7
8#[derive(PartialEq, Eq, Clone, Copy, Hash)]
9// TODO uncomment for a major release
10// #[repr(transparent)]
11/// A wrapper type that swaps (`<=` and `>=`) for `PartialOrd`s, (`meet` and `join`) for `Lattice`s,
12/// and (`top` and `bottom`) for `BoundedLattice`s.
13///
14/// # Example
15/// ```
16/// # use ascent_base::lattice::Dual;
17/// assert!(Dual(2) < Dual(1));
18/// ```
19pub struct Dual<T>(pub T);
20
21impl<T> Deref for Dual<T> {
22   type Target = T;
23   fn deref(&self) -> &Self::Target { &self.0 }
24}
25
26impl<T: Debug> Debug for Dual<T> {
27   fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }
28}
29
30impl<T: Display> Display for Dual<T> {
31   fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }
32}
33
34impl<T> PartialOrd for Dual<T>
35where T: PartialOrd
36{
37   fn partial_cmp(&self, other: &Self) -> Option<Ordering> { other.0.partial_cmp(&self.0) }
38}
39
40impl<T> Ord for Dual<T>
41where T: Ord
42{
43   fn cmp(&self, other: &Self) -> Ordering { other.0.cmp(&self.0) }
44}
45
46impl<T: Lattice> Lattice for Dual<T> {
47   #[inline]
48   fn meet(self, other: Self) -> Self { Dual(self.0.join(other.0)) }
49
50   #[inline]
51   fn join(self, other: Self) -> Self { Dual(self.0.meet(other.0)) }
52
53   #[inline]
54   fn meet_mut(&mut self, other: Self) -> bool { self.0.join_mut(other.0) }
55
56   #[inline]
57   fn join_mut(&mut self, other: Self) -> bool { self.0.meet_mut(other.0) }
58}
59
60impl<T: BoundedLattice> BoundedLattice for Dual<T> {
61   #[inline]
62   fn top() -> Self { Dual(T::bottom()) }
63
64   #[inline]
65   fn bottom() -> Self { Dual(T::top()) }
66}