Skip to content

Commit e29a524

Browse files
authored
Merge pull request #1028 from jturner314/cowrepr-dataowned
Make `CowArray` an owned storage array, require Clone bound for `into_shared`
2 parents f163e14 + 9681aba commit e29a524

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

src/arraytraits.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@
1010
use alloc::boxed::Box;
1111
#[cfg(not(feature = "std"))]
1212
use alloc::vec::Vec;
13+
use std::hash;
1314
use std::mem;
15+
use std::mem::size_of;
1416
use std::ops::{Index, IndexMut};
15-
use std::{hash, mem::size_of};
1617
use std::{iter::FromIterator, slice};
1718

1819
use crate::imp_prelude::*;
20+
use crate::Arc;
21+
1922
use crate::{
2023
dimension,
2124
iter::{Iter, IterMut},
2225
numeric_util,
2326
FoldWhile,
2427
NdIndex,
28+
OwnedArcRepr,
2529
Zip,
2630
};
2731

@@ -457,7 +461,9 @@ where D: Dimension
457461
{
458462
fn from(arr: Array<A, D>) -> ArcArray<A, D>
459463
{
460-
arr.into_shared()
464+
let data = OwnedArcRepr(Arc::new(arr.data));
465+
// safe because: equivalent unmoved data, ptr and dims remain valid
466+
unsafe { ArrayBase::from_data_ptr(data, arr.ptr).with_strides_dim(arr.strides, arr.dim) }
461467
}
462468
}
463469

src/data_traits.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {}
534534

535535
/// Array representation trait.
536536
///
537-
/// A representation that is a unique or shared owner of its data.
537+
/// A representation which can be the owner of its data.
538538
///
539539
/// ***Internal trait, see `Data`.***
540540
// The owned storage represents the ownership and allocation of the array's elements.
@@ -553,9 +553,13 @@ pub unsafe trait DataOwned: Data
553553
fn new(elements: Vec<Self::Elem>) -> Self;
554554

555555
/// Converts the data representation to a shared (copy on write)
556-
/// representation, without any copying.
556+
/// representation, cloning the array elements if necessary.
557557
#[doc(hidden)]
558-
fn into_shared(self) -> OwnedArcRepr<Self::Elem>;
558+
#[allow(clippy::wrong_self_convention)]
559+
fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
560+
where
561+
Self::Elem: Clone,
562+
D: Dimension;
559563
}
560564

561565
/// Array representation trait.
@@ -578,9 +582,12 @@ unsafe impl<A> DataOwned for OwnedRepr<A>
578582
OwnedRepr::from(elements)
579583
}
580584

581-
fn into_shared(self) -> OwnedArcRepr<A>
585+
fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
586+
where
587+
A: Clone,
588+
D: Dimension,
582589
{
583-
OwnedArcRepr(Arc::new(self))
590+
ArcArray::from(self_)
584591
}
585592
}
586593

@@ -593,9 +600,12 @@ unsafe impl<A> DataOwned for OwnedArcRepr<A>
593600
OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
594601
}
595602

596-
fn into_shared(self) -> OwnedArcRepr<A>
603+
fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
604+
where
605+
A: Clone,
606+
D: Dimension,
597607
{
598-
self
608+
self_
599609
}
600610
}
601611

@@ -720,6 +730,24 @@ unsafe impl<'a, A> Data for CowRepr<'a, A>
720730

721731
unsafe impl<'a, A> DataMut for CowRepr<'a, A> where A: Clone {}
722732

733+
unsafe impl<'a, A> DataOwned for CowRepr<'a, A>
734+
{
735+
type MaybeUninit = CowRepr<'a, MaybeUninit<A>>;
736+
737+
fn new(elements: Vec<A>) -> Self
738+
{
739+
CowRepr::Owned(OwnedRepr::new(elements))
740+
}
741+
742+
fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
743+
where
744+
A: Clone,
745+
D: Dimension,
746+
{
747+
self_.into_owned().into_shared()
748+
}
749+
}
750+
723751
/// Array representation trait.
724752
///
725753
/// The RawDataSubst trait maps the element type of array storage, while

src/impl_methods.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,17 @@ where
293293
}
294294

295295
/// Turn the array into a shared ownership (copy on write) array,
296-
/// without any copying.
296+
/// cloning the array elements if necessary.
297+
///
298+
/// If you want to generalize over `Array` and `ArcArray` inputs but avoid
299+
/// an `A: Clone` bound, use `Into::<ArcArray<A, D>>::into` instead of this
300+
/// method.
297301
pub fn into_shared(self) -> ArcArray<A, D>
298-
where S: DataOwned
302+
where
303+
A: Clone,
304+
S: DataOwned,
299305
{
300-
let data = self.data.into_shared();
301-
// safe because: equivalent unmoved data, ptr and dims remain valid
302-
unsafe { ArrayBase::from_data_ptr(data, self.ptr).with_strides_dim(self.strides, self.dim) }
306+
S::into_shared(self)
303307
}
304308

305309
/// Returns a reference to the first element of the array, or `None` if it

0 commit comments

Comments
 (0)