use std::fmt::{self, Debug};
use std::marker;
use std::mem;
use std::ops::{Index, IndexMut, Deref};
use base;
use base::Stride as Base;
#[repr(C)]
#[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct Stride<'a,T: 'a> {
base: Base<'a, T>,
_marker: marker::PhantomData<&'a mut T>,
}
unsafe impl<'a, T: Sync> Sync for Stride<'a, T> {}
unsafe impl<'a, T: Send> Send for Stride<'a, T> {}
impl<'a, T: Debug> Debug for Stride<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.base.fmt(f)
}
}
impl<'a, T> Stride<'a, T> {
#[inline(always)]
fn new_raw(base: Base<'a, T>) -> Stride<'a, T> {
Stride {
base: base,
_marker: marker::PhantomData
}
}
#[inline(always)]
pub fn new(x: &'a mut [T]) -> Stride<'a, T> {
Stride::new_raw(Base::new(x.as_mut_ptr(), x.len(), 1))
}
#[inline(always)]
pub fn len(&self) -> usize {
self.base.len()
}
#[inline(always)]
pub fn stride(&self) -> usize {
self.base.stride() / mem::size_of::<T>()
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.base.as_mut_ptr()
}
#[inline(always)]
pub fn reborrow<'b>(&'b mut self) -> Stride<'b, T> {
Stride::new_raw(self.base)
}
#[inline]
pub fn substrides2_mut(self) -> (Stride<'a, T>, Stride<'a, T>) {
let (l, r) = self.base.substrides2();
(Stride::new_raw(l), Stride::new_raw(r))
}
#[inline]
pub fn substrides_mut(self, n: usize) -> Substrides<'a, T> {
Substrides {
base: self.base.substrides(n),
}
}
#[inline]
pub fn get_mut<'b>(&'b mut self, n: usize) -> Option<&'b mut T> {
self.base.get_mut(n).map(|r| &mut *r)
}
#[inline]
pub fn iter_mut<'b>(&'b mut self) -> ::MutItems<'b, T> {
self.reborrow().into_iter()
}
#[inline]
pub fn into_iter(mut self) -> ::MutItems<'a, T> {
self.base.iter_mut()
}
#[inline]
pub fn slice_mut(self, from: usize, to: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice(from, to))
}
#[inline]
pub fn slice_from_mut(self, from: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice_from(from))
}
#[inline]
pub fn slice_to_mut(self, to: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice_to(to))
}
#[inline]
pub fn split_at_mut(self, idx: usize) -> (Stride<'a, T>, Stride<'a, T>) {
let (l, r) = self.base.split_at(idx);
(Stride::new_raw(l), Stride::new_raw(r))
}
}
impl<'a, T> Index<usize> for Stride<'a, T> {
type Output = T;
fn index<'b>(&'b self, n: usize) -> &'b T {
& (**self)[n]
}
}
impl<'a, T> IndexMut<usize> for Stride<'a, T> {
fn index_mut<'b>(&'b mut self, n: usize) -> &'b mut T {
self.get_mut(n).expect("Stride.index_mut: index out of bounds")
}
}
impl<'a, T> Deref for Stride<'a, T> {
type Target = ::imm::Stride<'a, T>;
fn deref<'b>(&'b self) -> &'b ::imm::Stride<'a, T> {
unsafe { mem::transmute(self) }
}
}
pub struct Substrides<'a, T: 'a> {
base: base::Substrides<'a, T>,
}
impl<'a, T> Iterator for Substrides<'a, T> {
type Item = Stride<'a, T>;
fn next(&mut self) -> Option<Stride<'a, T>> {
match self.base.next() {
Some(s) => Some(Stride::new_raw(s)),
None => None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
#[cfg(test)]
mod tests {
use super::Stride;
make_tests!(substrides2_mut, substrides_mut,
slice_mut, slice_to_mut, slice_from_mut, split_at_mut, get_mut, iter_mut, mut);
#[test]
fn reborrow() {
let v = &mut [1u8, 2, 3, 4, 5];
let mut s = Stride::new(v);
eq!(s.reborrow(), [1,2,3,4,5]);
eq!(s.reborrow(), [1,2,3,4,5]);
}
}