//! Ordered value wrapper use super::*; use std::{ cmp::Ordering, marker::PhantomData, borrow::{ Borrow, BorrowMut, }, ops, }; /// Provides external absolute ordering for references to type `T`. pub trait Orderer { fn order(a: &T, b: &T) -> Ordering; } /// The default `Orderer` used in `Ordered`. /// Implemented for all `T: Ord`. #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] pub enum DefaultOrderProvider{} impl Orderer for DefaultOrderProvider { #[inline] fn order(a: &T, b: &T) -> Ordering { Ord::cmp(a, b) } } /// Provides an external ordering for a value `T` #[derive(Debug, Clone, Hash, Copy)] pub struct Ordered = DefaultOrderProvider>(PhantomData>, T); impl> Ordered { #[inline] pub fn new(value: T) -> Self { Self(PhantomData, value) } #[inline] pub fn into_inner(self) -> T { self.1 } } impl> Ordered { #[inline] pub fn inner(&self) -> &T { &self.1 } #[inline] pub fn inner_mut(&mut self) -> &mut T { &mut self.1 } } impl> Borrow for Ordered { #[inline] fn borrow(&self) -> &T { self.inner() } } impl> BorrowMut for Ordered { #[inline] fn borrow_mut(&mut self) -> &mut T { self.inner_mut() } } impl> AsRef for Ordered { #[inline] fn as_ref(&self) -> &T { self.inner() } } impl> AsMut for Ordered { #[inline] fn as_mut(&mut self) -> &mut T { self.inner_mut() } } impl> ops::Deref for Ordered { type Target = T; #[inline] fn deref(&self) -> &T { self.inner() } } impl> ops::DerefMut for Ordered { #[inline] fn deref_mut(&mut self) -> &mut T { self.inner_mut() } } impl Eq for Ordered where O: Orderer{} impl PartialEq for Ordered where O: Orderer { #[inline] fn eq(&self, other: &Self) -> bool { O::order(&self.1, &other.1).is_eq() } } impl Ord for Ordered where O: Orderer { #[inline] fn cmp(&self, other: &Self) -> Ordering { O::order(&self.1, &other.1) } } impl PartialOrd for Ordered where O: Orderer { fn partial_cmp(&self, other: &Self) -> Option { Some(O::order(&self.1, &other.1)) } }