use std::mem;
use std::rc::Rc;
use {
ArrayBase,
Dimension,
ViewRepr,
};
pub unsafe trait Data {
type Elem;
#[doc(hidden)]
fn slice(&self) -> &[Self::Elem];
}
pub unsafe trait DataMut : Data {
#[doc(hidden)]
fn slice_mut(&mut self) -> &mut [Self::Elem];
#[doc(hidden)]
#[inline]
fn ensure_unique<D>(&mut ArrayBase<Self, D>)
where Self: Sized,
D: Dimension
{ }
#[doc(hidden)]
#[inline]
fn is_unique(&mut self) -> bool {
true
}
}
pub unsafe trait DataClone : Data {
#[doc(hidden)]
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem);
}
unsafe impl<A> Data for Rc<Vec<A>> {
type Elem = A;
fn slice(&self) -> &[A] {
self
}
}
unsafe impl<A> DataMut for Rc<Vec<A>>
where A: Clone
{
fn slice_mut(&mut self) -> &mut [A] {
&mut Rc::make_mut(self)[..]
}
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
where Self: Sized,
D: Dimension
{
if Rc::get_mut(&mut self_.data).is_some() {
return;
}
if self_.dim.size() <= self_.data.len() / 2 {
unsafe {
*self_ = ArrayBase::from_vec_dim_unchecked(self_.dim.clone(),
self_.iter()
.cloned()
.collect());
}
return;
}
let our_off = (self_.ptr as isize - self_.data.as_ptr() as isize) /
mem::size_of::<A>() as isize;
let rvec = Rc::make_mut(&mut self_.data);
unsafe {
self_.ptr = rvec.as_mut_ptr().offset(our_off);
}
}
fn is_unique(&mut self) -> bool {
Rc::get_mut(self).is_some()
}
}
unsafe impl<A> DataClone for Rc<Vec<A>> {
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
(self.clone(), ptr)
}
}
unsafe impl<A> Data for Vec<A> {
type Elem = A;
fn slice(&self) -> &[A] {
self
}
}
unsafe impl<A> DataMut for Vec<A> {
fn slice_mut(&mut self) -> &mut [A] {
self
}
}
unsafe impl<A> DataClone for Vec<A>
where A: Clone
{
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
let mut u = self.clone();
let our_off = (self.as_ptr() as isize - ptr as isize) /
mem::size_of::<A>() as isize;
let new_ptr = u.as_mut_ptr().offset(our_off);
(u, new_ptr)
}
}
unsafe impl<'a, A> Data for ViewRepr<&'a A> {
type Elem = A;
fn slice(&self) -> &[A] {
&[]
}
}
unsafe impl<'a, A> DataClone for ViewRepr<&'a A> {
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
(*self, ptr)
}
}
unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
type Elem = A;
fn slice(&self) -> &[A] {
&[]
}
}
unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {
fn slice_mut(&mut self) -> &mut [A] {
&mut []
}
}
pub unsafe trait DataOwned : Data {
#[doc(hidden)]
fn new(elements: Vec<Self::Elem>) -> Self;
#[doc(hidden)]
fn into_shared(self) -> Rc<Vec<Self::Elem>>;
}
pub unsafe trait DataShared : Clone + DataClone { }
unsafe impl<A> DataShared for Rc<Vec<A>> {}
unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
unsafe impl<A> DataOwned for Vec<A> {
fn new(elements: Vec<A>) -> Self {
elements
}
fn into_shared(self) -> Rc<Vec<A>> {
Rc::new(self)
}
}
unsafe impl<A> DataOwned for Rc<Vec<A>> {
fn new(elements: Vec<A>) -> Self {
Rc::new(elements)
}
fn into_shared(self) -> Rc<Vec<A>> {
self
}
}