#![cfg(feature = "lru")]
use core::hash::Hash;
use std::fmt::Debug;
pub trait IndexType: Copy + Eq + Hash + Debug + 'static {
const NONE: Self;
const ZERO: Self;
fn as_usize(self) -> usize;
fn from_usize(i: usize) -> Self;
fn inc(self) -> Self;
fn dec(self) -> Self;
fn is_zero(self) -> bool;
}
impl IndexType for u8 {
const NONE: Self = 255;
const ZERO: Self = 0;
#[inline(always)]
fn as_usize(self) -> usize {
self as usize
}
#[inline(always)]
fn from_usize(i: usize) -> Self {
i as u8
}
#[inline(always)]
fn inc(self) -> Self {
self + 1
}
#[inline(always)]
fn dec(self) -> Self {
self - 1
}
#[inline(always)]
fn is_zero(self) -> bool {
self == 0
}
}
impl IndexType for u16 {
const NONE: Self = 65535;
const ZERO: Self = 0;
#[inline(always)]
fn as_usize(self) -> usize {
self as usize
}
#[inline(always)]
fn from_usize(i: usize) -> Self {
i as u16
}
#[inline(always)]
fn inc(self) -> Self {
self + 1
}
#[inline(always)]
fn dec(self) -> Self {
self - 1
}
#[inline(always)]
fn is_zero(self) -> bool {
self == 0
}
}
#[cfg(test)]
mod tests {
use super::*;
fn test_index_type<I: IndexType>() {
let zero = I::ZERO;
assert!(zero.is_zero());
assert_eq!(zero.as_usize(), 0);
let one = zero.inc();
assert!(!one.is_zero());
assert_eq!(one.as_usize(), 1);
let zero_again = one.dec();
assert!(zero_again.is_zero());
let from = I::from_usize(10);
assert_eq!(from.as_usize(), 10);
let none = I::NONE;
assert_ne!(none.as_usize(), 0);
}
#[test]
fn test_u8_index() {
test_index_type::<u8>();
}
#[test]
fn test_u16_index() {
test_index_type::<u16>();
}
}