use serde::{Serialize, de};
use std::{fmt, ops::Not};
use crate::KeyEnDeOrdered;
pub trait SlotType:
Clone
+ Ord
+ fmt::Debug
+ Not<Output = Self>
+ KeyEnDeOrdered
+ Serialize
+ de::DeserializeOwned
+ 'static
{
const MIN: Self;
const MAX: Self;
fn floor_align(&self, base: &Self) -> Self;
fn checked_pow(&self, exp: u32) -> Option<Self>;
fn max_val(self, other: Self) -> Self;
fn saturating_add(&self, rhs: &Self) -> Self;
fn as_i128(&self) -> i128;
fn as_u64(&self) -> u64;
}
macro_rules! impl_slot_type {
($($t:ty),+) => { $(
impl SlotType for $t {
const MIN: Self = <$t>::MIN;
const MAX: Self = <$t>::MAX;
#[inline]
fn floor_align(&self, base: &Self) -> Self { self / base * base }
#[inline]
fn checked_pow(&self, exp: u32) -> Option<Self> { <$t>::checked_pow(*self, exp) }
#[inline]
fn max_val(self, other: Self) -> Self { Ord::max(self, other) }
#[inline]
fn saturating_add(&self, rhs: &Self) -> Self { <$t>::saturating_add(*self, *rhs) }
#[inline]
fn as_i128(&self) -> i128 { i128::try_from(*self).unwrap_or(i128::MAX) }
#[inline]
fn as_u64(&self) -> u64 { *self as u64 }
}
)+ };
}
impl_slot_type!(u32, u64, u128);