use std::fmt::{self, Debug};
use std::mem;
use std::ops::Index;
use base;
use base::Stride as Base;
#[repr(C)]
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct Stride<'a,T: 'a> {
base: Base<'a, T>,
}
impl<'a, T> Copy for Stride<'a, T> {}
impl<'a, T> Clone for Stride<'a, T> {
fn clone(&self) -> Stride<'a, T> { *self }
}
unsafe impl<'a, T: Sync> Sync for Stride<'a, T> {}
unsafe impl<'a, T: Sync> 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,
}
}
#[inline(always)]
pub fn new(x: &'a [T]) -> Stride<'a, T> {
Stride::new_raw(Base::new(x.as_ptr() as *mut _, 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_ptr(&self) -> *const T {
self.base.as_mut_ptr() as *const T
}
#[inline(always)]
#[cfg(test)]
fn reborrow<'b>(&'b self) -> Stride<'b, T> {
*self
}
#[inline]
pub fn substrides2(&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(&self, n: usize) -> Substrides<'a, T> {
Substrides {
base: self.base.substrides(n),
}
}
#[inline]
pub fn get(&self, n: usize) -> Option<&'a T> {
self.base.get(n)
}
#[inline]
pub fn iter(&self) -> ::Items<'a, T> {
self.base.iter()
}
#[inline]
pub fn slice(&self, from: usize, to: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice(from, to))
}
#[inline]
pub fn slice_from(&self, from: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice_from(from))
}
#[inline]
pub fn slice_to(&self, to: usize) -> Stride<'a, T> {
Stride::new_raw(self.base.slice_to(to))
}
#[inline]
pub fn split_at(&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.get(n).expect("Stride.index: index out of bounds")
}
}
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)]
#[allow(unused_mut)]
mod tests {
use super::Stride;
make_tests!(substrides2, substrides, slice, slice_to, slice_from, split_at, get, iter, );
}