Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Created March 31, 2020 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DutchGhost/7dc1522cc44458425df54500d16001b9 to your computer and use it in GitHub Desktop.
Save DutchGhost/7dc1522cc44458425df54500d16001b9 to your computer and use it in GitHub Desktop.
ChunksExact reduced
use std::marker::PhantomData;
use std::slice;
pub fn chunks_exact<T>(slice: &[T], chunk_size: usize) -> ChunksExact<'_, T> {
assert!(chunk_size != 0);
let rem = slice.len() % chunk_size;
let len = slice.len() - rem;
let (fst, snd) = slice.split_at(len);
let len = fst.len();
let chunks_begin = fst.as_ptr();
let chunks_end = unsafe { chunks_begin.offset(len as isize) };
let len = snd.len();
let end = unsafe { snd.as_ptr().offset(len as isize) };
ChunksExact {
chunks_begin,
chunks_end,
end,
chunk_size,
phantom: PhantomData,
}
}
pub struct ChunksExact<'a, T> {
chunks_begin: *const T,
chunks_end: *const T,
end: *const T,
chunk_size: usize,
phantom: PhantomData<&'a T>,
}
impl<T> ChunksExact<'_, T> {
pub fn remainder(&self) -> &[T] {
unsafe {
let len = (self.end as usize - self.chunks_end as usize) / std::mem::size_of::<T>();
dbg!(len);
slice::from_raw_parts(self.chunks_end, len)
}
}
}
impl<'a, T> Iterator for ChunksExact<'a, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.chunks_begin >= self.chunks_end {
None
} else {
let slice = unsafe { slice::from_raw_parts(self.chunks_begin, self.chunk_size) };
self.chunks_begin = unsafe { self.chunks_begin.offset(self.chunk_size as isize) };
Some(slice)
}
}
}
fn main() {
let slice = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let mut chunk = chunks_exact(slice, 3);
for s in chunk.by_ref() {
dbg!(s);
}
dbg!(chunk.remainder());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment