#![no_std]
use core::borrow::Borrow;
use core::cmp::Ordering::{self, Less, Equal, Greater};
use core::default::Default;
use core::marker::PhantomData;
use core::fmt::{self, Debug};
pub fn max<'a, C: ?Sized, T: ?Sized>(cmp: &C, l: &'a T, r: &'a T) -> &'a T
where C: Compare<T> {
if cmp.compares_ge(r, l) { r } else { l }
}
pub fn min<'a, C: ?Sized, T: ?Sized>(cmp: &C, l: &'a T, r: &'a T) -> &'a T
where C: Compare<T> {
if cmp.compares_le(l, r) { l } else { r }
}
pub trait Compare<L: ?Sized, R: ?Sized = L> {
fn compare(&self, l: &L, r: &R) -> Ordering;
fn compares_lt(&self, l: &L, r: &R) -> bool { self.compare(l, r) == Less }
fn compares_le(&self, l: &L, r: &R) -> bool { self.compare(l, r) != Greater }
fn compares_ge(&self, l: &L, r: &R) -> bool { self.compare(l, r) != Less }
fn compares_gt(&self, l: &L, r: &R) -> bool { self.compare(l, r) == Greater }
fn compares_eq(&self, l: &L, r: &R) -> bool { self.compare(l, r) == Equal }
fn compares_ne(&self, l: &L, r: &R) -> bool { self.compare(l, r) != Equal }
fn borrowing(self) -> Borrowing<Self, L, R> where Self: Sized { Borrowing(self, PhantomData) }
fn rev(self) -> Rev<Self> where Self: Sized { Rev(self) }
fn swap(self) -> Swap<Self> where Self: Sized { Swap(self) }
fn then<D>(self, then: D) -> Then<Self, D> where D: Compare<L, R>, Self: Sized {
Then(self, then)
}
}
impl<F: ?Sized, L: ?Sized, R: ?Sized> Compare<L, R> for F
where F: Fn(&L, &R) -> Ordering {
fn compare(&self, l: &L, r: &R) -> Ordering { (*self)(l, r) }
}
pub struct Borrowing<C, Lb: ?Sized, Rb: ?Sized = Lb>(C, PhantomData<fn(&Lb, &Rb)>)
where C: Compare<Lb, Rb>;
impl<C, L: ?Sized, R: ?Sized, Lb: ?Sized, Rb: ?Sized> Compare<L, R> for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb>, L: Borrow<Lb>, R: Borrow<Rb> {
fn compare(&self, l: &L, r: &R) -> Ordering { self.0.compare(l.borrow(), r.borrow()) }
fn compares_lt(&self, l: &L, r: &R) -> bool { self.0.compares_lt(l.borrow(), r.borrow()) }
fn compares_le(&self, l: &L, r: &R) -> bool { self.0.compares_le(l.borrow(), r.borrow()) }
fn compares_ge(&self, l: &L, r: &R) -> bool { self.0.compares_ge(l.borrow(), r.borrow()) }
fn compares_gt(&self, l: &L, r: &R) -> bool { self.0.compares_gt(l.borrow(), r.borrow()) }
fn compares_eq(&self, l: &L, r: &R) -> bool { self.0.compares_eq(l.borrow(), r.borrow()) }
fn compares_ne(&self, l: &L, r: &R) -> bool { self.0.compares_ne(l.borrow(), r.borrow()) }
}
impl<C, Lb: ?Sized, Rb: ?Sized> Clone for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb> + Clone {
fn clone(&self) -> Self { Borrowing(self.0.clone(), PhantomData) }
}
impl<C, Lb: ?Sized, Rb: ?Sized> Copy for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb> + Copy {}
impl<C, Lb: ?Sized, Rb: ?Sized> Default for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb> + Default {
fn default() -> Self { Borrowing(Default::default(), PhantomData) }
}
impl<C, Lb: ?Sized, Rb: ?Sized> PartialEq for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb> + PartialEq {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<C, Lb: ?Sized, Rb: ?Sized> Eq for Borrowing<C, Lb, Rb> where C: Compare<Lb, Rb> + Eq {}
impl<C, Lb: ?Sized, Rb: ?Sized> Debug for Borrowing<C, Lb, Rb>
where C: Compare<Lb, Rb> + Debug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Borrowing({:?})", self.0) }
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Extract<E, C> {
ext: E,
cmp: C,
}
impl<E, K> Extract<E, Natural<K>> where K: Ord {
pub fn new<T: ?Sized>(ext: E) -> Self where E: Fn(&T) -> K {
Extract { ext: ext, cmp: natural() }
}
}
impl<E, C> Extract<E, C> {
pub fn with_cmp<T: ?Sized, K>(ext: E, cmp: C) -> Self
where E: Fn(&T) -> K, C: Compare<K> { Extract { ext: ext, cmp: cmp } }
}
impl<E, C, T: ?Sized, K> Compare<T> for Extract<E, C> where E: Fn(&T) -> K, C: Compare<K> {
fn compare(&self, l: &T, r: &T) -> Ordering {
self.cmp.compare(&(self.ext)(l), &(self.ext)(r))
}
fn compares_lt(&self, l: &T, r: &T) -> bool {
self.cmp.compares_lt(&(self.ext)(l), &(self.ext)(r))
}
fn compares_le(&self, l: &T, r: &T) -> bool {
self.cmp.compares_le(&(self.ext)(l), &(self.ext)(r))
}
fn compares_ge(&self, l: &T, r: &T) -> bool {
self.cmp.compares_ge(&(self.ext)(l), &(self.ext)(r))
}
fn compares_gt(&self, l: &T, r: &T) -> bool {
self.cmp.compares_gt(&(self.ext)(l), &(self.ext)(r))
}
fn compares_eq(&self, l: &T, r: &T) -> bool {
self.cmp.compares_eq(&(self.ext)(l), &(self.ext)(r))
}
fn compares_ne(&self, l: &T, r: &T) -> bool {
self.cmp.compares_ne(&(self.ext)(l), &(self.ext)(r))
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
pub struct Then<C, D>(C, D);
impl<C, D, L: ?Sized, R: ?Sized> Compare<L, R> for Then<C, D>
where C: Compare<L, R>, D: Compare<L, R> {
fn compare(&self, l: &L, r: &R) -> Ordering {
match self.0.compare(l, r) {
Equal => self.1.compare(l, r),
order => order,
}
}
}
pub struct Natural<T: Ord + ?Sized>(PhantomData<fn(&T)>);
pub fn natural<T: Ord + ?Sized>() -> Natural<T> { Natural(PhantomData) }
impl<T: Ord + ?Sized> Compare<T> for Natural<T> {
fn compare(&self, l: &T, r: &T) -> Ordering { Ord::cmp(l, r) }
fn compares_lt(&self, l: &T, r: &T) -> bool { PartialOrd::lt(l, r) }
fn compares_le(&self, l: &T, r: &T) -> bool { PartialOrd::le(l, r) }
fn compares_ge(&self, l: &T, r: &T) -> bool { PartialOrd::ge(l, r) }
fn compares_gt(&self, l: &T, r: &T) -> bool { PartialOrd::gt(l, r) }
fn compares_eq(&self, l: &T, r: &T) -> bool { PartialEq::eq(l, r) }
fn compares_ne(&self, l: &T, r: &T) -> bool { PartialEq::ne(l, r) }
}
impl<T: Ord + ?Sized> Clone for Natural<T> {
fn clone(&self) -> Self { *self }
}
impl<T: Ord + ?Sized> Copy for Natural<T> {}
impl<T: Ord + ?Sized> Default for Natural<T> {
fn default() -> Self { natural() }
}
impl<T: Ord + ?Sized> PartialEq for Natural<T> {
fn eq(&self, _other: &Self) -> bool { true }
}
impl<T: Ord + ?Sized> Eq for Natural<T> {}
impl<T: Ord + ?Sized> Debug for Natural<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Natural") }
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
pub struct Rev<C>(C);
impl<C, L: ?Sized, R: ?Sized> Compare<L, R> for Rev<C> where C: Compare<L, R> {
fn compare(&self, l: &L, r: &R) -> Ordering { self.0.compare(l, r).reverse() }
fn compares_lt(&self, l: &L, r: &R) -> bool { self.0.compares_gt(l, r) }
fn compares_le(&self, l: &L, r: &R) -> bool { self.0.compares_ge(l, r) }
fn compares_ge(&self, l: &L, r: &R) -> bool { self.0.compares_le(l, r) }
fn compares_gt(&self, l: &L, r: &R) -> bool { self.0.compares_lt(l, r) }
fn compares_eq(&self, l: &L, r: &R) -> bool { self.0.compares_eq(l, r) }
fn compares_ne(&self, l: &L, r: &R) -> bool { self.0.compares_ne(l, r) }
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
pub struct Swap<C>(C);
impl<C, L: ?Sized, R: ?Sized> Compare<R, L> for Swap<C>
where C: Compare<L, R> {
fn compare(&self, r: &R, l: &L) -> Ordering { self.0.compare(l, r) }
fn compares_lt(&self, r: &R, l: &L) -> bool { self.0.compares_lt(l, r) }
fn compares_le(&self, r: &R, l: &L) -> bool { self.0.compares_le(l, r) }
fn compares_ge(&self, r: &R, l: &L) -> bool { self.0.compares_ge(l, r) }
fn compares_gt(&self, r: &R, l: &L) -> bool { self.0.compares_gt(l, r) }
fn compares_eq(&self, r: &R, l: &L) -> bool { self.0.compares_eq(l, r) }
fn compares_ne(&self, r: &R, l: &L) -> bool { self.0.compares_ne(l, r) }
}