use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut};
use num::Zero;
use num_iter::{Range, range};
use super::*;
use arith::{Less, GreaterEqual, compare};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Ix<'l> {
len: PhantomData<Val<'l, usize>>,
inner: usize,
}
impl<'l> Ix<'l> {
pub fn new<'i>(index: Val<'i, usize>,
_: Less<Val<'i, usize>, Val<'l, usize>>)
-> Self {
unsafe { Self::from_raw(index.into_inner()) }
}
pub fn try_new(index: usize, len: Val<'l, usize>) -> Option<Self> {
imprint(index, |i| {
match compare(&i, &len) {
Ok(lt) => Some(Self::new(i, lt)),
Err(_) => None,
}
})
}
pub fn check<'m>(self, _: GreaterEqual<Val<'m, usize>, Val<'l, usize>>)
-> Ix<'m> {
unsafe { Ix::from_raw(self.into_inner()) }
}
pub unsafe fn from_raw(index: usize) -> Self {
Ix { len: PhantomData, inner: index }
}
}
impl<'i> fmt::Debug for Ix<'i> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("Ix(")?;
(*self).fmt(f)?;
f.write_str(")")
}
}
impl<'l> AsRef<usize> for Ix<'l> {
fn as_ref(&self) -> &usize {
&**self
}
}
impl<'l> Borrow<usize> for Ix<'l> {
fn borrow(&self) -> &usize {
&**self
}
}
impl<'l> Deref for Ix<'l> {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'l> IntoInner for Ix<'l> {
fn into_inner(self) -> Self::Target {
self.inner
}
}
pub struct BoxedSl<'l, T> {
len: PhantomData<Val<'l, usize>>,
inner: Box<[T]>,
}
impl<'l, T> BoxedSl<'l, T> {
pub fn from_boxed_slice(boxed_slice: Box<[T]>, len: Val<'l, usize>)
-> Result<Self, Box<[T]>> {
if boxed_slice.len() == len.into_inner() {
Ok(unsafe { Self::from_raw(boxed_slice) })
} else {
Err(boxed_slice)
}
}
pub fn new(len: Val<'l, usize>, value: T) -> Self where T: Clone {
unsafe { Self::from_raw(
vec![value; len.into_inner()].into_boxed_slice()
) }
}
pub unsafe fn from_raw(boxed_slice: Box<[T]>) -> Self {
BoxedSl {
len: PhantomData,
inner: boxed_slice,
}
}
pub fn len(&self) -> Val<'l, usize> {
unsafe { Val::known((**self).len()) }
}
pub fn as_slice<'a>(&'a self) -> Sl<'a, 'l, T> {
unsafe { Sl::from_raw((**self).as_ptr()) }
}
pub fn as_mut_slice<'a>(&'a mut self) -> MutSl<'a, 'l, T> {
unsafe { MutSl::from_raw((**self).as_mut_ptr()) }
}
}
impl<'l, T> Deref for BoxedSl<'l, T> {
type Target = Box<[T]>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'l, T> DerefMut for BoxedSl<'l, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'l, T> IntoInner for BoxedSl<'l, T> {
fn into_inner(self) -> Self::Target {
self.inner
}
}
impl<'a, 'l, T: fmt::Debug> fmt::Debug for BoxedSl<'l, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("BoxedSl(")?;
self.inner.fmt(f)?;
f.write_str(")")
}
}
impl<'l, T> Index<Ix<'l>> for BoxedSl<'l, T> {
type Output = T;
fn index(&self, index: Ix<'l>) -> &Self::Output {
unsafe { self.inner.get_unchecked(index.into_inner()) }
}
}
impl<'l, T> IndexMut<Ix<'l>> for BoxedSl<'l, T> {
fn index_mut<'a>(&'a mut self, index: Ix<'l>) -> &'a mut Self::Output {
unsafe { self.inner.get_unchecked_mut(index.into_inner()) }
}
}
#[derive(Clone, Copy)]
pub struct Sl<'a, 'l, T: 'a> {
len: PhantomData<(Val<'l, usize>, &'a T)>,
ptr: *const T,
}
impl<'a, 'l, T> Sl<'a, 'l, T> {
pub fn from_slice(slice: &'a [T], len: Val<'l, usize>) -> Option<Self> {
if slice.len() == len.into_inner() {
Some(unsafe { Self::from_raw(slice.as_ptr()) })
} else {
None
}
}
pub unsafe fn from_raw(ptr: *const T) -> Self {
Sl { len: PhantomData, ptr: ptr }
}
pub fn as_ptr(self) -> *const T {
self.ptr
}
pub fn as_slice(self, len: Val<'l, usize>) -> &'a [T] {
use std::slice;
unsafe { slice::from_raw_parts(self.as_ptr(), len.into_inner()) }
}
}
impl<'a, 'l, T> fmt::Debug for Sl<'a, 'l, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("Sl(")?;
self.ptr.fmt(f)?;
f.write_str(")")
}
}
impl<'a, 'l, T> Index<Ix<'l>> for Sl<'a, 'l, T> {
type Output = T;
fn index(&self, index: Ix<'l>) -> &Self::Output {
unsafe { &*self.ptr.offset(index.into_inner() as isize) }
}
}
pub struct MutSl<'a, 'l, T: 'a> {
len: PhantomData<(Val<'l, usize>, &'a mut T)>,
ptr: *mut T,
}
impl<'a, 'l, T> MutSl<'a, 'l, T> {
pub fn from_slice(slice: &'a mut [T], len: Val<'l, usize>)
-> Option<Self> {
if slice.len() == len.into_inner() {
Some(unsafe { Self::from_raw(slice.as_mut_ptr()) })
} else {
None
}
}
pub fn as_slice<'b>(&'b self, len: Val<'l, usize>) -> &'b [T] {
use std::slice;
unsafe { slice::from_raw_parts_mut(self.ptr, len.into_inner()) }
}
pub fn into_slice(self, len: Val<'l, usize>) -> &'a mut [T] {
use std::slice;
unsafe { slice::from_raw_parts_mut(self.ptr, len.into_inner()) }
}
pub unsafe fn from_raw(ptr: *mut T) -> Self {
MutSl { len: PhantomData, ptr: ptr }
}
pub fn as_ptr(self) -> *const T {
self.ptr
}
pub fn as_mut_ptr(self) -> *mut T {
self.ptr
}
}
impl<'a, 'l, T> fmt::Debug for MutSl<'a, 'l, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("MutSl(")?;
self.ptr.fmt(f)?;
f.write_str(")")
}
}
impl<'a, 'l, T> Index<Ix<'l>> for MutSl<'a, 'l, T> {
type Output = T;
fn index(&self, index: Ix<'l>) -> &Self::Output {
unsafe { &*self.ptr.offset(index.into_inner() as isize) }
}
}
impl<'a, 'l, T> IndexMut<Ix<'l>> for MutSl<'a, 'l, T> {
fn index_mut(&mut self, index: Ix<'l>) -> &mut Self::Output {
unsafe { &mut *self.ptr.offset(index.into_inner() as isize) }
}
}
#[derive(Clone)]
pub struct IxRange<'l> {
len: PhantomData<Val<'l, usize>>,
inner: Range<usize>,
}
impl<'l> IxRange<'l> {
pub fn new(start: usize, stop: Ix<'l>) -> Self {
unsafe { Self::from_raw(start, stop.into_inner()) }
}
pub fn new_to(stop: Ix<'l>) -> Self {
Self::new(Zero::zero(), stop)
}
pub fn new_inclusive(start: usize, stop_inclusive: Ix<'l>) -> Self {
unsafe { Self::from_raw(start, stop_inclusive.into_inner() + 1) }
}
pub fn new_to_inclusive(stop_inclusive: Ix<'l>) -> Self {
Self::new_inclusive(Zero::zero(), stop_inclusive)
}
pub fn new_from(start: usize, len: Val<'l, usize>) -> Self {
unsafe { Self::from_raw(start, len.into_inner()) }
}
pub fn new_full(len: Val<'l, usize>) -> Self {
Self::new_from(Zero::zero(), len)
}
pub unsafe fn from_raw(start: usize, stop: usize) -> Self {
IxRange {
len: PhantomData,
inner: range(start, stop),
}
}
}
impl<'l> Deref for IxRange<'l> {
type Target = Range<usize>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'l> DerefMut for IxRange<'l> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'l> Iterator for IxRange<'l> {
type Item = Ix<'l>;
fn next(&mut self) -> Option<Self::Item> {
(**self).next().map(|i| unsafe { Ix::from_raw(i) })
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
impl<'l> DoubleEndedIterator for IxRange<'l> {
fn next_back(&mut self) -> Option<Self::Item> {
(**self).next_back().map(|i| unsafe { Ix::from_raw(i) })
}
}
#[cfg(test)]
mod tests {
use super::super::*;
use super::*;
#[test]
fn it_works() {
let n_ = 42;
imprint(n_, |n| {
let vec: Vec<usize> = (0 .. n_).collect();
let slice = Sl::from_slice(&vec, n).unwrap();
let mut a = BoxedSl::new(n, 0.0);
let mut b = BoxedSl::new(n, 0.0);
for i in IxRange::new_full(n) {
let i_ = *i;
a[i] = i_ as f64 * 0.5;
b[i] = (n_ - i_) as f64;
}
for i in IxRange::new_full(n) {
let i_ = *i;
assert_eq!(slice[i], i_);
assert_eq!(a[i], i_ as f64 * 0.5);
assert_eq!(b[i], (n_ - i_) as f64);
}
})
}
}