diff --git a/src/data_repr.rs b/src/data_repr.rs
new file mode 100644
index 000000000..c7a8b96fa
--- /dev/null
+++ b/src/data_repr.rs
@@ -0,0 +1,97 @@
+
+use std::mem;
+use std::ptr::NonNull;
+use std::slice;
+use crate::extension::nonnull;
+
+/// Array's representation.
+///
+/// *Don’t use this type directly—use the type alias
+/// [`Array`](type.Array.html) for the array type!*
+// Like a Vec, but with non-unique ownership semantics
+#[derive(Debug)]
+pub struct OwnedRepr {
+ ptr: NonNull,
+ len: usize,
+ capacity: usize,
+}
+
+impl OwnedRepr {
+ pub(crate) fn from(mut v: Vec) -> Self {
+ let len = v.len();
+ let capacity = v.capacity();
+ let ptr = nonnull::nonnull_from_vec_data(&mut v);
+ mem::forget(v);
+ Self {
+ ptr,
+ len,
+ capacity,
+ }
+ }
+
+ pub(crate) fn into_vec(mut self) -> Vec {
+ let v = self.take_as_vec();
+ mem::forget(self);
+ v
+ }
+
+ pub(crate) fn as_slice(&self) -> &[A] {
+ unsafe {
+ slice::from_raw_parts(self.ptr.as_ptr(), self.len)
+ }
+ }
+
+ pub(crate) fn len(&self) -> usize { self.len }
+
+ pub(crate) fn as_ptr(&self) -> *const A {
+ self.ptr.as_ptr()
+ }
+
+ pub(crate) fn as_nonnull_mut(&mut self) -> NonNull {
+ self.ptr
+ }
+
+ fn take_as_vec(&mut self) -> Vec {
+ let capacity = self.capacity;
+ let len = self.len;
+ self.len = 0;
+ self.capacity = 0;
+ unsafe {
+ Vec::from_raw_parts(self.ptr.as_ptr(), len, capacity)
+ }
+ }
+}
+
+impl Clone for OwnedRepr
+ where A: Clone
+{
+ fn clone(&self) -> Self {
+ Self::from(self.as_slice().to_owned())
+ }
+
+ fn clone_from(&mut self, other: &Self) {
+ let mut v = self.take_as_vec();
+ let other = other.as_slice();
+
+ if v.len() > other.len() {
+ v.truncate(other.len());
+ }
+ let (front, back) = other.split_at(v.len());
+ v.clone_from_slice(front);
+ v.extend_from_slice(back);
+ *self = Self::from(v);
+ }
+}
+
+impl Drop for OwnedRepr {
+ fn drop(&mut self) {
+ if self.capacity > 0 {
+ // drop as a Vec.
+ self.take_as_vec();
+ }
+ }
+}
+
+unsafe impl Sync for OwnedRepr where A: Sync { }
+unsafe impl Send for OwnedRepr where A: Send { }
+
diff --git a/src/data_traits.rs b/src/data_traits.rs
index b3f07959e..7e04561bc 100644
--- a/src/data_traits.rs
+++ b/src/data_traits.rs
@@ -8,7 +8,6 @@
//! The data (inner representation) traits for ndarray
-use crate::extension::nonnull::nonnull_from_vec_data;
use rawpointer::PointerExt;
use std::mem::{self, size_of};
use std::ptr::NonNull;
@@ -188,7 +187,7 @@ unsafe impl RawDataClone for RawViewRepr<*mut A> {
unsafe impl RawData for OwnedArcRepr {
type Elem = A;
fn _data_slice(&self) -> Option<&[A]> {
- Some(&self.0)
+ Some(self.0.as_slice())
}
private_impl! {}
}
@@ -226,7 +225,7 @@ where
};
let rvec = Arc::make_mut(rcvec);
unsafe {
- self_.ptr = nonnull_from_vec_data(rvec).offset(our_off);
+ self_.ptr = rvec.as_nonnull_mut().offset(our_off);
}
}
@@ -242,7 +241,7 @@ unsafe impl Data for OwnedArcRepr {
D: Dimension,
{
Self::ensure_unique(&mut self_);
- let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap());
+ let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
ArrayBase {
data,
ptr: self_.ptr,
@@ -264,7 +263,7 @@ unsafe impl RawDataClone for OwnedArcRepr {
unsafe impl RawData for OwnedRepr {
type Elem = A;
fn _data_slice(&self) -> Option<&[A]> {
- Some(&self.0)
+ Some(self.as_slice())
}
private_impl! {}
}
@@ -303,10 +302,10 @@ where
{
unsafe fn clone_with_ptr(&self, ptr: NonNull) -> (Self, NonNull) {
let mut u = self.clone();
- let mut new_ptr = nonnull_from_vec_data(&mut u.0);
+ let mut new_ptr = u.as_nonnull_mut();
if size_of::() != 0 {
let our_off =
- (ptr.as_ptr() as isize - self.0.as_ptr() as isize) / mem::size_of::() as isize;
+ (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::() as isize;
new_ptr = new_ptr.offset(our_off);
}
(u, new_ptr)
@@ -318,12 +317,12 @@ where
ptr: NonNull,
) -> NonNull {
let our_off = if size_of::() != 0 {
- (ptr.as_ptr() as isize - other.0.as_ptr() as isize) / mem::size_of::() as isize
+ (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::() as isize
} else {
0
};
- self.0.clone_from(&other.0);
- nonnull_from_vec_data(&mut self.0).offset(our_off)
+ self.clone_from(&other);
+ self.as_nonnull_mut().offset(our_off)
}
}
@@ -413,16 +412,16 @@ unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
unsafe impl DataOwned for OwnedRepr {
fn new(elements: Vec) -> Self {
- OwnedRepr(elements)
+ OwnedRepr::from(elements)
}
fn into_shared(self) -> OwnedRcRepr {
- OwnedArcRepr(Arc::new(self.0))
+ OwnedArcRepr(Arc::new(self))
}
}
unsafe impl DataOwned for OwnedArcRepr {
fn new(elements: Vec) -> Self {
- OwnedArcRepr(Arc::new(elements))
+ OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
}
fn into_shared(self) -> OwnedRcRepr {
diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs
index 96075593f..687452f9b 100644
--- a/src/impl_owned_array.rs
+++ b/src/impl_owned_array.rs
@@ -19,22 +19,22 @@ impl Array {
/// let scalar: Foo = array.into_scalar();
/// assert_eq!(scalar, Foo);
/// ```
- pub fn into_scalar(mut self) -> A {
+ pub fn into_scalar(self) -> A {
let size = ::std::mem::size_of::();
if size == 0 {
// Any index in the `Vec` is fine since all elements are identical.
- self.data.0.remove(0)
+ self.data.into_vec().remove(0)
} else {
// Find the index in the `Vec` corresponding to `self.ptr`.
// (This is necessary because the element in the array might not be
// the first element in the `Vec`, such as if the array was created
// by `array![1, 2, 3, 4].slice_move(s![2])`.)
let first = self.ptr.as_ptr() as usize;
- let base = self.data.0.as_ptr() as usize;
+ let base = self.data.as_ptr() as usize;
let index = (first - base) / size;
debug_assert_eq!((first - base) % size, 0);
// Remove the element at the index and return it.
- self.data.0.remove(index)
+ self.data.into_vec().remove(index)
}
}
}
@@ -54,6 +54,6 @@ where
/// If the array is in standard memory layout, the logical element order
/// of the array (`.iter()` order) and of the returned vector will be the same.
pub fn into_raw_vec(self) -> Vec {
- self.data.0
+ self.data.into_vec()
}
}
diff --git a/src/lib.rs b/src/lib.rs
index f9a208df1..32830d3b3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -150,6 +150,7 @@ mod array_serde;
mod arrayformat;
mod arraytraits;
mod data_traits;
+mod data_repr;
pub use crate::aliases::*;
@@ -1386,12 +1387,8 @@ pub type RawArrayView = ArrayBase, D>;
/// [`from_shape_ptr`](#method.from_shape_ptr) for details.
pub type RawArrayViewMut = ArrayBase, D>;
-/// Array's representation.
-///
-/// *Don’t use this type directly—use the type alias
-/// [`Array`](type.Array.html) for the array type!*
-#[derive(Clone, Debug)]
-pub struct OwnedRepr(Vec);
+pub use data_repr::OwnedRepr;
+
/// RcArray's representation.
///
@@ -1405,7 +1402,7 @@ pub use self::OwnedArcRepr as OwnedRcRepr;
/// *Don’t use this type directly—use the type alias
/// [`ArcArray`](type.ArcArray.html) for the array type!*
#[derive(Debug)]
-pub struct OwnedArcRepr(Arc>);
+pub struct OwnedArcRepr(Arc>);
impl Clone for OwnedArcRepr {
fn clone(&self) -> Self {