use std::ops::Add;
use dupe::Dupe;
#[derive(
Copy,
Clone,
Dupe,
Debug,
PartialOrd,
Ord,
PartialEq,
Eq,
Hash,
derive_more::Display
)]
#[display(fmt = "&{}", _0)]
pub(crate) struct BcSlot(pub(crate) u32);
impl BcSlot {
pub(crate) fn to_in(self) -> BcSlotIn {
BcSlotIn(self)
}
pub(crate) fn to_out(self) -> BcSlotOut {
BcSlotOut(self)
}
}
impl Add<u32> for BcSlot {
type Output = BcSlot;
#[inline]
fn add(self, rhs: u32) -> BcSlot {
BcSlot(self.0 + rhs)
}
}
#[derive(Copy, Clone, Dupe, Debug)]
pub(crate) struct BcSlotsN<const N: usize> {
pub(crate) start: BcSlot,
}
impl<const N: usize> BcSlotsN<N> {
#[inline]
pub(crate) fn get<const I: u32>(self) -> BcSlot {
assert!((I as usize) < N);
self.start + I
}
pub(crate) fn from_range(range: BcSlotRange) -> BcSlotsN<N> {
assert_eq!(N, range.len() as usize);
BcSlotsN { start: range.start }
}
}
#[derive(Copy, Clone, Dupe, Debug, derive_more::Display)]
#[display(fmt = "{}..{}", start, end)]
pub(crate) struct BcSlotRange {
pub(crate) start: BcSlot,
pub(crate) end: BcSlot,
}
impl BcSlotRange {
#[inline]
pub(crate) fn len(self) -> u32 {
self.end.0 - self.start.0
}
pub(crate) fn iter(self) -> impl Iterator<Item = BcSlot> {
(self.start.0..self.end.0).map(BcSlot)
}
pub(crate) fn to_in(self) -> BcSlotInRange {
BcSlotInRange {
start: self.start.to_in(),
end: self.end.to_in(),
}
}
}
#[derive(Copy, Clone, Dupe, Debug)]
pub(crate) struct BcSlotRangeFrom(pub(crate) BcSlot);
#[derive(Debug, Copy, Clone, Dupe, derive_more::Display, PartialEq, Eq)]
pub(crate) struct BcSlotIn(BcSlot);
impl Add<u32> for BcSlotIn {
type Output = BcSlotIn;
#[inline]
fn add(self, rhs: u32) -> BcSlotIn {
BcSlotIn(self.0 + rhs)
}
}
impl BcSlotIn {
#[inline]
pub(crate) fn get(self) -> BcSlot {
self.0
}
}
#[derive(Copy, Clone, Dupe, Debug, derive_more::Display)]
#[display(fmt = "{}..{}", start, end)]
pub(crate) struct BcSlotInRange {
pub(crate) start: BcSlotIn,
pub(crate) end: BcSlotIn,
}
impl Default for BcSlotInRange {
fn default() -> Self {
BcSlotInRange {
start: BcSlotIn(BcSlot(0)),
end: BcSlotIn(BcSlot(0)),
}
}
}
impl BcSlotInRange {
#[inline]
pub(crate) fn len(self) -> u32 {
self.end.0.0 - self.start.0.0
}
pub(crate) fn to_range_from(self) -> BcSlotInRangeFrom {
BcSlotInRangeFrom(self.start)
}
pub(crate) fn iter(self) -> impl Iterator<Item = BcSlotIn> {
(self.start.0.0..self.end.0.0).map(|s| BcSlotIn(BcSlot(s)))
}
pub(crate) fn try_push(&mut self, slot: BcSlotIn) -> bool {
if self.len() == 0 {
*self = BcSlotInRange {
start: slot,
end: slot + 1,
};
true
} else if self.end == slot {
self.end = slot + 1;
true
} else {
false
}
}
}
#[derive(Copy, Clone, Dupe, Debug)]
pub(crate) struct BcSlotInRangeFrom(pub(crate) BcSlotIn);
impl BcSlotInRangeFrom {
#[inline]
pub(crate) fn to_range(self, len: u32) -> BcSlotInRange {
BcSlotInRange {
start: self.0,
end: self.0 + len,
}
}
}
#[derive(Debug, Copy, Clone, Dupe, derive_more::Display)]
pub(crate) struct BcSlotOut(BcSlot);
impl BcSlotOut {
#[inline]
pub(crate) fn get(self) -> BcSlot {
self.0
}
}