#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BodyHandle(u64);
impl BodyHandle {
pub const fn from_parts(index: u32, generation: u32) -> Self {
Self(((index as u64) << 32) | generation as u64)
}
pub const fn index(self) -> u32 {
(self.0 >> 32) as u32
}
pub const fn generation(self) -> u32 {
self.0 as u32
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parts_round_trip() {
for (index, generation) in [(0, 0), (1, 0), (0, 1), (7, 3), (u32::MAX, u32::MAX)] {
let handle = BodyHandle::from_parts(index, generation);
assert_eq!(handle.index(), index);
assert_eq!(handle.generation(), generation);
}
}
#[test]
fn a_reused_slot_is_a_different_handle() {
let first = BodyHandle::from_parts(4, 0);
let reused = BodyHandle::from_parts(4, 1);
assert_ne!(first, reused, "the generation must distinguish the slot");
}
#[test]
fn handles_order_by_slot_then_generation() {
let mut handles = [
BodyHandle::from_parts(2, 0),
BodyHandle::from_parts(1, 5),
BodyHandle::from_parts(1, 2),
];
handles.sort();
assert_eq!(
handles,
[
BodyHandle::from_parts(1, 2),
BodyHandle::from_parts(1, 5),
BodyHandle::from_parts(2, 0),
]
);
}
}