#[cfg(debug_assertions)]
use std::any;
use std::any::TypeId;
use std::borrow::Borrow;
use std::num::NonZeroU32;
use std::{cmp, fmt, hash, ops};
pub trait Ref {
type Target: ?Sized;
const MUTABLE: bool;
fn as_ref(&self) -> &Self::Target;
}
impl<T: ?Sized> Ref for &T {
type Target = T;
const MUTABLE: bool = false;
fn as_ref(&self) -> &T { self }
}
impl<T: ?Sized> Ref for &mut T {
type Target = T;
const MUTABLE: bool = true;
fn as_ref(&self) -> &T { self }
}
#[derive(Clone, Copy)]
pub struct DoubleDeref<T>(pub T);
impl<T> ops::Deref for DoubleDeref<T>
where
T: ops::Deref,
T::Target: ops::Deref,
{
type Target = <T::Target as ops::Deref>::Target;
fn deref(&self) -> &Self::Target { &self.0 }
}
#[derive(Debug, Clone, Copy)]
pub struct DbgTypeId {
pub id: TypeId,
#[cfg(debug_assertions)]
name: &'static str,
}
impl DbgTypeId {
pub fn of<T: 'static>() -> Self {
Self {
id: TypeId::of::<T>(),
#[cfg(debug_assertions)]
name: any::type_name::<T>(),
}
}
}
impl fmt::Display for DbgTypeId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[cfg(debug_assertions)]
{
write!(f, "{}", self.name)
}
#[cfg(not(debug_assertions))]
{
write!(f, "{:?}", self.id)
}
}
}
impl PartialEq for DbgTypeId {
fn eq(&self, other: &Self) -> bool { self.id == other.id }
}
impl PartialEq<TypeId> for DbgTypeId {
fn eq(&self, other: &TypeId) -> bool { self.id == *other }
}
impl Eq for DbgTypeId {}
impl PartialOrd for DbgTypeId {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) }
}
impl Ord for DbgTypeId {
fn cmp(&self, other: &Self) -> cmp::Ordering { self.id.cmp(&other.id) }
}
impl hash::Hash for DbgTypeId {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
<TypeId as hash::Hash>::hash(&self.id, state);
}
}
impl Borrow<TypeId> for DbgTypeId {
fn borrow(&self) -> &TypeId { &self.id }
}
pub unsafe trait UnsafeEqOrd: Eq + Ord {}
unsafe impl UnsafeEqOrd for NonZeroU32 {}
unsafe impl UnsafeEqOrd for usize {}