You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
enumerate-ordered/src/order.rs

138 lines
2.7 KiB

//! 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<T: ?Sized>
{
fn order(a: &T, b: &T) -> Ordering;
}
/// The default `Orderer<T>` used in `Ordered<T>`.
/// Implemented for all `T: Ord`.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)]
pub enum DefaultOrderProvider{}
impl<T: ?Sized + Ord> Orderer<T> 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<T: ?Sized, O: ?Sized + Orderer<T> = DefaultOrderProvider>(PhantomData<Box<O>>, T);
impl<T, O: ?Sized + Orderer<T>> Ordered<T, O>
{
#[inline]
pub fn new(value: T) -> Self
{
Self(PhantomData, value)
}
#[inline]
pub fn into_inner(self) -> T
{
self.1
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> Ordered<T, O>
{
#[inline]
pub fn inner(&self) -> &T
{
&self.1
}
#[inline]
pub fn inner_mut(&mut self) -> &mut T
{
&mut self.1
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> Borrow<T> for Ordered<T, O>
{
#[inline]
fn borrow(&self) -> &T {
self.inner()
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> BorrowMut<T> for Ordered<T, O>
{
#[inline]
fn borrow_mut(&mut self) -> &mut T {
self.inner_mut()
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> AsRef<T> for Ordered<T, O>
{
#[inline]
fn as_ref(&self) -> &T {
self.inner()
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> AsMut<T> for Ordered<T, O>
{
#[inline]
fn as_mut(&mut self) -> &mut T {
self.inner_mut()
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> ops::Deref for Ordered<T, O>
{
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.inner()
}
}
impl<T: ?Sized, O: ?Sized + Orderer<T>> ops::DerefMut for Ordered<T, O>
{
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.inner_mut()
}
}
impl<T: ?Sized, O: ?Sized> Eq for Ordered<T, O> where O: Orderer<T>{}
impl<T: ?Sized, O: ?Sized> PartialEq for Ordered<T, O>
where O: Orderer<T>
{
#[inline]
fn eq(&self, other: &Self) -> bool
{
O::order(&self.1, &other.1).is_eq()
}
}
impl<T: ?Sized, O: ?Sized> Ord for Ordered<T, O>
where O: Orderer<T>
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering
{
O::order(&self.1, &other.1)
}
}
impl<T: ?Sized, O: ?Sized> PartialOrd for Ordered<T, O>
where O: Orderer<T>
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(O::order(&self.1, &other.1))
}
}