#[derive(Debug, Clone, Copy, Default)]
pub struct RankIndex {
abs: u32,
rel_lo: u32,
rel_hi: u32,
}
impl RankIndex {
#[inline]
pub fn new() -> Self {
RankIndex {
abs: 0,
rel_lo: 0,
rel_hi: 0,
}
}
#[inline]
pub fn set_abs(&mut self, value: usize) {
debug_assert!(value <= u32::MAX as usize);
self.abs = value as u32;
}
#[inline]
pub fn set_rel1(&mut self, value: usize) {
debug_assert!(value <= 64);
self.rel_lo = (self.rel_lo & !0x7F) | ((value as u32) & 0x7F);
}
#[inline]
pub fn set_rel2(&mut self, value: usize) {
debug_assert!(value <= 128);
self.rel_lo = (self.rel_lo & !(0xFF << 7)) | (((value as u32) & 0xFF) << 7);
}
#[inline]
pub fn set_rel3(&mut self, value: usize) {
debug_assert!(value <= 192);
self.rel_lo = (self.rel_lo & !(0xFF << 15)) | (((value as u32) & 0xFF) << 15);
}
#[inline]
pub fn set_rel4(&mut self, value: usize) {
debug_assert!(value <= 256);
self.rel_lo = (self.rel_lo & !(0x1FF << 23)) | (((value as u32) & 0x1FF) << 23);
}
#[inline]
pub fn set_rel5(&mut self, value: usize) {
debug_assert!(value <= 320);
self.rel_hi = (self.rel_hi & !0x1FF) | ((value as u32) & 0x1FF);
}
#[inline]
pub fn set_rel6(&mut self, value: usize) {
debug_assert!(value <= 384);
self.rel_hi = (self.rel_hi & !(0x1FF << 9)) | (((value as u32) & 0x1FF) << 9);
}
#[inline]
pub fn set_rel7(&mut self, value: usize) {
debug_assert!(value <= 448);
self.rel_hi = (self.rel_hi & !(0x1FF << 18)) | (((value as u32) & 0x1FF) << 18);
}
#[inline]
pub fn abs(&self) -> usize {
self.abs as usize
}
#[inline]
pub fn rel1(&self) -> usize {
(self.rel_lo & 0x7F) as usize
}
#[inline]
pub fn rel2(&self) -> usize {
((self.rel_lo >> 7) & 0xFF) as usize
}
#[inline]
pub fn rel3(&self) -> usize {
((self.rel_lo >> 15) & 0xFF) as usize
}
#[inline]
pub fn rel4(&self) -> usize {
((self.rel_lo >> 23) & 0x1FF) as usize
}
#[inline]
pub fn rel5(&self) -> usize {
(self.rel_hi & 0x1FF) as usize
}
#[inline]
pub fn rel6(&self) -> usize {
((self.rel_hi >> 9) & 0x1FF) as usize
}
#[inline]
pub fn rel7(&self) -> usize {
((self.rel_hi >> 18) & 0x1FF) as usize
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rank_index_default() {
let rank = RankIndex::new();
assert_eq!(rank.abs(), 0);
assert_eq!(rank.rel1(), 0);
assert_eq!(rank.rel2(), 0);
assert_eq!(rank.rel3(), 0);
assert_eq!(rank.rel4(), 0);
assert_eq!(rank.rel5(), 0);
assert_eq!(rank.rel6(), 0);
assert_eq!(rank.rel7(), 0);
}
#[test]
fn test_rank_index_abs() {
let mut rank = RankIndex::new();
rank.set_abs(12345);
assert_eq!(rank.abs(), 12345);
}
#[test]
fn test_rank_index_rel1() {
let mut rank = RankIndex::new();
rank.set_rel1(64);
assert_eq!(rank.rel1(), 64);
}
#[test]
fn test_rank_index_rel2() {
let mut rank = RankIndex::new();
rank.set_rel2(128);
assert_eq!(rank.rel2(), 128);
}
#[test]
fn test_rank_index_multiple() {
let mut rank = RankIndex::new();
rank.set_abs(1000);
rank.set_rel1(10);
rank.set_rel2(20);
rank.set_rel3(30);
rank.set_rel4(40);
rank.set_rel5(50);
rank.set_rel6(60);
rank.set_rel7(70);
assert_eq!(rank.abs(), 1000);
assert_eq!(rank.rel1(), 10);
assert_eq!(rank.rel2(), 20);
assert_eq!(rank.rel3(), 30);
assert_eq!(rank.rel4(), 40);
assert_eq!(rank.rel5(), 50);
assert_eq!(rank.rel6(), 60);
assert_eq!(rank.rel7(), 70);
}
}