ascent_base 0.8.1

support library for the ascent package
Documentation
use std::cmp::Ordering;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref;

use super::BoundedLattice;
use crate::Lattice;

#[derive(PartialEq, Eq, Clone, Copy, Hash)]
// TODO uncomment for a major release
// #[repr(transparent)]
/// A wrapper type that swaps (`<=` and `>=`) for `PartialOrd`s, (`meet` and `join`) for `Lattice`s,
/// and (`top` and `bottom`) for `BoundedLattice`s.
///
/// # Example
/// ```
/// # use ascent_base::lattice::Dual;
/// assert!(Dual(2) < Dual(1));
/// ```
pub struct Dual<T>(pub T);

impl<T> Deref for Dual<T> {
   type Target = T;
   fn deref(&self) -> &Self::Target { &self.0 }
}

impl<T: Debug> Debug for Dual<T> {
   fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }
}

impl<T: Display> Display for Dual<T> {
   fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }
}

impl<T> PartialOrd for Dual<T>
where T: PartialOrd
{
   fn partial_cmp(&self, other: &Self) -> Option<Ordering> { other.0.partial_cmp(&self.0) }
}

impl<T> Ord for Dual<T>
where T: Ord
{
   fn cmp(&self, other: &Self) -> Ordering { other.0.cmp(&self.0) }
}

impl<T: Lattice> Lattice for Dual<T> {
   #[inline]
   fn meet(self, other: Self) -> Self { Dual(self.0.join(other.0)) }

   #[inline]
   fn join(self, other: Self) -> Self { Dual(self.0.meet(other.0)) }

   #[inline]
   fn meet_mut(&mut self, other: Self) -> bool { self.0.join_mut(other.0) }

   #[inline]
   fn join_mut(&mut self, other: Self) -> bool { self.0.meet_mut(other.0) }
}

impl<T: BoundedLattice> BoundedLattice for Dual<T> {
   #[inline]
   fn top() -> Self { Dual(T::bottom()) }

   #[inline]
   fn bottom() -> Self { Dual(T::top()) }
}