use crate::config::Config;
#[cfg(feature = "alloc")]
use crate::config::DefaultConfig;
use crate::key_layout::KeyLayout;
use crate::key_piece::KeyPiece;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
type Layout<C> = <C as Config>::Layout;
type Repr<C> = <Layout<C> as KeyLayout<<C as Config>::Idx, <C as Config>::Gen>>::Repr;
pub struct Key<
#[cfg(feature = "alloc")] C: Config = DefaultConfig,
#[cfg(not(feature = "alloc"))] C: Config,
> {
repr: Repr<C>,
}
impl<C: Config> Key<C> {
#[inline]
pub fn idx(&self) -> C::Idx {
<Layout<C> as KeyLayout<C::Idx, C::Gen>>::idx(self.repr)
}
#[inline]
pub fn generation(&self) -> C::Gen {
let generation = <Layout<C> as KeyLayout<C::Idx, C::Gen>>::generation(self.repr);
C::Gen::from_non_zero(generation)
}
#[inline]
pub fn non_zero_generation(&self) -> <C::Gen as KeyPiece>::NonZero {
<Layout<C> as KeyLayout<C::Idx, C::Gen>>::generation(self.repr)
}
#[inline]
pub fn is_max_generation(&self) -> bool {
self.generation() == <Layout<C> as KeyLayout<C::Idx, C::Gen>>::max_generation()
}
#[inline]
pub unsafe fn from_raw_parts(idx: C::Idx, generation: <C::Gen as KeyPiece>::NonZero) -> Self {
let generation = C::Gen::from_non_zero(generation);
debug_assert!(generation.is_odd());
let repr =
unsafe { <Layout<C> as KeyLayout<C::Idx, C::Gen>>::pack_unchecked(idx, generation) };
Self { repr }
}
}
impl<C: Config> Clone for Key<C> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<C: Config> Copy for Key<C> {}
impl<C: Config> PartialEq for Key<C> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.repr == other.repr
}
}
impl<C: Config> Eq for Key<C> {}
impl<C: Config> PartialOrd for Key<C> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<C: Config> Ord for Key<C> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.idx()
.cmp(&other.idx())
.then(self.generation().cmp(&other.generation()))
}
}
impl<C: Config> Hash for Key<C> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.repr.hash(state);
}
}
impl<C: Config> fmt::Debug for Key<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Key")
.field("idx", &self.idx())
.field("generation", &self.generation())
.finish()
}
}