linear-deque 0.1.3

A double-ended queue that can be sliced at any time without preparation.
Documentation
use core::mem;
use core::ptr::{self, NonNull};

pub struct RawValIter<T> {
    start: *const T,
    end: *const T,
}

impl<T> RawValIter<T> {
    pub unsafe fn new(slice: &[T]) -> Self {
        unsafe {
            RawValIter {
                start: slice.as_ptr(),
                end: if mem::size_of::<T>() == 0 {
                    ((slice.as_ptr() as usize) + slice.len()) as *const _
                } else if slice.is_empty() {
                    slice.as_ptr()
                } else {
                    slice.as_ptr().add(slice.len())
                },
            }
        }
    }
}

impl<T> Iterator for RawValIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        if self.start == self.end {
            None
        } else {
            unsafe {
                if mem::size_of::<T>() == 0 {
                    self.start = (self.start as usize + 1) as *const _;
                    Some(ptr::read(NonNull::<T>::dangling().as_ptr()))
                } else {
                    let old_ptr = self.start;
                    self.start = self.start.add(1);
                    Some(ptr::read(old_ptr))
                }
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = (self.end as usize - self.start as usize) / mem::size_of::<T>().max(1);
        (len, Some(len))
    }
}

impl<T> DoubleEndedIterator for RawValIter<T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.start == self.end {
            None
        } else {
            unsafe {
                if mem::size_of::<T>() == 0 {
                    self.end = (self.end as usize - 1) as *const _;
                    Some(ptr::read(NonNull::<T>::dangling().as_ptr()))
                } else {
                    self.end = self.end.sub(1);
                    Some(ptr::read(self.end))
                }
            }
        }
    }
}