use std::{
fmt::{Debug, Display},
hash::Hash,
};
mod impl_borrowed_fd;
use impl_borrowed_fd as current_impl;
pub mod alloc;
pub mod intern;
pub mod sparse_map;
pub mod sparse_set;
pub mod vec;
#[derive(Clone, Copy)]
pub struct RawIndex(current_impl::ImplType);
impl RawIndex {
pub const ZERO: RawIndex = unsafe { RawIndex::from_u32_unchecked(0) };
pub const fn from_u32(x: u32) -> Option<RawIndex> {
if x == 0xffff_ffff {
return None;
}
unsafe { Some(RawIndex(current_impl::from_u32_unchecked(x))) }
}
pub const unsafe fn from_u32_unchecked(x: u32) -> RawIndex {
debug_assert!(x != 0xffff_ffff);
unsafe { RawIndex(current_impl::from_u32_unchecked(x)) }
}
pub const fn as_u32(self) -> u32 {
current_impl::to_u32(self.0)
}
}
const _: () = {
assert!(size_of::<RawIndex>() == 4);
assert!(size_of::<Option<RawIndex>>() == 4);
};
impl PartialEq for RawIndex {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.as_u32() == other.as_u32()
}
}
impl Eq for RawIndex {}
impl PartialOrd for RawIndex {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_u32().partial_cmp(&other.as_u32())
}
}
impl Ord for RawIndex {
#[inline(always)]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_u32().cmp(&other.as_u32())
}
}
impl Hash for RawIndex {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_u32().hash(state);
}
}
impl Debug for RawIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_u32())
}
}
impl Display for RawIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_u32())
}
}
pub unsafe trait Idx: Copy + 'static + Eq + Ord + Debug + Hash {
fn new(idx: u64) -> Self;
fn index(self) -> u64;
}
unsafe impl Idx for u32 {
fn new(idx: u64) -> u32 {
assert!(idx < (u32::MAX as u64));
idx as u32
}
fn index(self) -> u64 {
self as u64
}
}
#[macro_export]
macro_rules! index_type {
($v:vis $name:ident $(<$($x:ident $(: $x_def:path)?),* $(,)?>)? $(as $fmt:literal)? $(where $($where_bounds:tt)*)?) => {
$v struct $name $(<$($x: 'static $( + $x_def)?),*>)?(pub $crate::index::RawIndex $(, ::core::marker::PhantomData<($($x,)*)>)?) $(where $($where_bounds)*)?;
#[allow(dead_code)]
impl $(<$($x $(: $x_def)?),*>)? $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
$v const ZERO: Self = Self($crate::index::RawIndex::ZERO $(, ::core::marker::PhantomData::<($($x,)*)>)?);
}
unsafe impl $(<$($x $(: $x_def)?),*>)? $crate::index::Idx for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn new(idx: u64) -> Self {
assert!(idx < 0xffff_ffff);
$name(unsafe { $crate::index::RawIndex::from_u32_unchecked(idx as u32) } $($(${ignore($x)})* , ::core::marker::PhantomData)?)
}
fn index(self) -> u64 {
self.0.as_u32() as u64
}
}
impl $(<$($x $(: $x_def)?),*>)? ::core::fmt::Debug for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
f.debug_tuple(stringify!($name)).field(&self.0).finish()
}
}
impl $(<$($x $(: $x_def)?),*>)? ::core::clone::Clone for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn clone(&self) -> Self { *self }
}
impl $(<$($x $(: $x_def)?),*>)? ::core::cmp::PartialEq for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl $(<$($x $(: $x_def)?),*>)? ::core::cmp::Eq for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {}
impl $(<$($x $(: $x_def)?),*>)? ::core::cmp::PartialOrd for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn partial_cmp(&self, other: &Self) -> ::core::option::Option<::core::cmp::Ordering> { ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) }
}
impl $(<$($x $(: $x_def)?),*>)? ::core::cmp::Ord for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering { ::core::cmp::Ord::cmp(&self.0, &other.0) }
}
impl $(<$($x $(: $x_def)?),*>)? ::core::hash::Hash for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {
fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
state.write_u32(self.0.as_u32())
}
}
impl $(<$($x $(: $x_def)?),*>)? ::core::marker::Copy for $name $(<$($x),*>)? $(where $($where_bounds:tt)*)? {}
impl $(<$($x $(: $x_def)?),*>)? $(${ignore($fmt)} ::core::fmt::Display for)? $name $(<$($x),*>)? where $($($x: ::core::fmt::Display),*)? $(, $($where_bounds:tt)*)? {
$(fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, $fmt, self.0)
})?
}
};
}