diff --git a/src/arraytraits.rs b/src/arraytraits.rs
index 2f72cea2f..e68b5d56a 100644
--- a/src/arraytraits.rs
+++ b/src/arraytraits.rs
@@ -10,18 +10,22 @@
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
+use std::hash;
use std::mem;
+use std::mem::size_of;
use std::ops::{Index, IndexMut};
-use std::{hash, mem::size_of};
use std::{iter::FromIterator, slice};
use crate::imp_prelude::*;
+use crate::Arc;
+
use crate::{
dimension,
iter::{Iter, IterMut},
numeric_util,
FoldWhile,
NdIndex,
+ OwnedArcRepr,
Zip,
};
@@ -457,7 +461,9 @@ where D: Dimension
{
fn from(arr: Array) -> ArcArray
{
- arr.into_shared()
+ let data = OwnedArcRepr(Arc::new(arr.data));
+ // safe because: equivalent unmoved data, ptr and dims remain valid
+ unsafe { ArrayBase::from_data_ptr(data, arr.ptr).with_strides_dim(arr.strides, arr.dim) }
}
}
diff --git a/src/data_traits.rs b/src/data_traits.rs
index 5ed856f4d..5dfb90e37 100644
--- a/src/data_traits.rs
+++ b/src/data_traits.rs
@@ -534,7 +534,7 @@ unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {}
/// Array representation trait.
///
-/// A representation that is a unique or shared owner of its data.
+/// A representation which can be the owner of its data.
///
/// ***Internal trait, see `Data`.***
// The owned storage represents the ownership and allocation of the array's elements.
@@ -553,9 +553,13 @@ pub unsafe trait DataOwned: Data
fn new(elements: Vec) -> Self;
/// Converts the data representation to a shared (copy on write)
- /// representation, without any copying.
+ /// representation, cloning the array elements if necessary.
#[doc(hidden)]
- fn into_shared(self) -> OwnedArcRepr;
+ #[allow(clippy::wrong_self_convention)]
+ fn into_shared(self_: ArrayBase) -> ArcArray
+ where
+ Self::Elem: Clone,
+ D: Dimension;
}
/// Array representation trait.
@@ -578,9 +582,12 @@ unsafe impl DataOwned for OwnedRepr
OwnedRepr::from(elements)
}
- fn into_shared(self) -> OwnedArcRepr
+ fn into_shared(self_: ArrayBase) -> ArcArray
+ where
+ A: Clone,
+ D: Dimension,
{
- OwnedArcRepr(Arc::new(self))
+ ArcArray::from(self_)
}
}
@@ -593,9 +600,12 @@ unsafe impl DataOwned for OwnedArcRepr
OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
}
- fn into_shared(self) -> OwnedArcRepr
+ fn into_shared(self_: ArrayBase) -> ArcArray
+ where
+ A: Clone,
+ D: Dimension,
{
- self
+ self_
}
}
@@ -720,6 +730,24 @@ unsafe impl<'a, A> Data for CowRepr<'a, A>
unsafe impl<'a, A> DataMut for CowRepr<'a, A> where A: Clone {}
+unsafe impl<'a, A> DataOwned for CowRepr<'a, A>
+{
+ type MaybeUninit = CowRepr<'a, MaybeUninit>;
+
+ fn new(elements: Vec) -> Self
+ {
+ CowRepr::Owned(OwnedRepr::new(elements))
+ }
+
+ fn into_shared(self_: ArrayBase) -> ArcArray
+ where
+ A: Clone,
+ D: Dimension,
+ {
+ self_.into_owned().into_shared()
+ }
+}
+
/// Array representation trait.
///
/// The RawDataSubst trait maps the element type of array storage, while
diff --git a/src/impl_methods.rs b/src/impl_methods.rs
index 076e155ba..1fe633e10 100644
--- a/src/impl_methods.rs
+++ b/src/impl_methods.rs
@@ -292,13 +292,17 @@ where
}
/// Turn the array into a shared ownership (copy on write) array,
- /// without any copying.
+ /// cloning the array elements if necessary.
+ ///
+ /// If you want to generalize over `Array` and `ArcArray` inputs but avoid
+ /// an `A: Clone` bound, use `Into::>::into` instead of this
+ /// method.
pub fn into_shared(self) -> ArcArray
- where S: DataOwned
+ where
+ A: Clone,
+ S: DataOwned,
{
- let data = self.data.into_shared();
- // safe because: equivalent unmoved data, ptr and dims remain valid
- unsafe { ArrayBase::from_data_ptr(data, self.ptr).with_strides_dim(self.strides, self.dim) }
+ S::into_shared(self)
}
/// Returns a reference to the first element of the array, or `None` if it