use std::ops::{Mul, Range};
use num_traits::Unsigned;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Span<Idx: Unsigned + Copy> {
pub start: Idx,
pub len: Idx,
}
impl<Idx: Unsigned + Copy> Span<Idx> {
#[inline]
pub fn end(&self) -> Idx {
self.start + self.len
}
#[inline]
pub fn range(self) -> Range<Idx> {
let Self { start, len } = self;
Range {
start,
end: start + len,
}
}
pub fn try_cast<Narrow>(self) -> Option<Span<Narrow>>
where
Narrow: TryFrom<Idx> + Unsigned + Copy,
{
Some(Span {
start: self.start.try_into().ok()?,
len: self.len.try_into().ok()?,
})
}
}
impl Span<u32> {
#[inline]
pub fn range_usize(self) -> Range<usize> {
let Self { start, len } = self;
Range {
start: start as usize,
end: start as usize + len as usize,
}
}
}
impl<Idx: Unsigned + Copy> From<Span<Idx>> for Range<Idx> {
#[inline]
fn from(value: Span<Idx>) -> Self {
value.range()
}
}
impl<Idx: Unsigned + Copy + Mul> Mul<Idx> for Span<Idx> {
type Output = Self;
fn mul(self, rhs: Idx) -> Self::Output {
let Self { start, len } = self;
Self {
start: rhs * start,
len: rhs * len,
}
}
}