use std::{num::NonZero, ops};
use crate::base::{marker::ThreadBound, num::bounded};
pub unsafe trait Select<'id>: Sized {
fn bounds(self) -> ops::Range<usize>;
}
pub struct Window<'a, const NUMBER: usize, const SAMPLE: usize> {
bytes: &'a mut [u8],
at: NonZero<usize>,
_thread: ThreadBound,
}
impl<'a, const NUMBER: usize, const SAMPLE: usize> Window<'a, NUMBER, SAMPLE> {
pub fn try_at(bytes: &'a mut [u8], at: NonZero<usize>) -> Option<Self> {
const { assert!(NUMBER <= usize::MAX - SAMPLE, "bounds") };
if bytes.get(at.get()..)?.len() < NUMBER + SAMPLE {
return None;
}
Some(Self {
bytes,
at,
_thread: ThreadBound::NEW,
})
}
pub fn parts(&mut self) -> (&mut u8, &mut [u8; NUMBER], &[u8; SAMPLE]) {
let source = self.bytes.as_mut_ptr();
unsafe {
(
&mut *source,
&mut *source.add(self.at.get()).cast::<[u8; NUMBER]>(),
&*source.add(self.at.get() + NUMBER).cast::<[u8; SAMPLE]>(),
)
}
}
pub fn split<const MAX: u64>(
self,
position: bounded::U64<0, MAX>,
) -> (&'a mut [u8], &'a mut [u8]) {
const { assert!((MAX as u128) < NUMBER as u128, "bounds") };
let len = self.at.get() + position.get() as usize + 1;
unsafe { self.bytes.split_at_mut_unchecked(len) }
}
}