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.
138 lines
2.7 KiB
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))
|
|
}
|
|
}
|