From be3aa20f837d8a247cfea417e80c379b63cb7b78 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Sat, 5 Jun 2021 17:27:51 -0400 Subject: [PATCH 1/2] Add A: Clone bound to into_shared --- src/arraytraits.rs | 10 ++++++++-- src/data_traits.rs | 22 ++++++++++++++++------ src/impl_methods.rs | 14 +++++++++----- 3 files changed, 33 insertions(+), 13 deletions(-) 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..8ac978046 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -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_ } } 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 From 9681ababca251c4aa8c88bfe069dfce74f48ffcb Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Mon, 31 May 2021 21:59:21 -0400 Subject: [PATCH 2/2] Implement DataOwned for CowRepr --- src/data_traits.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/data_traits.rs b/src/data_traits.rs index 8ac978046..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. @@ -730,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