Skip to content

Commit ac970a1

Browse files
committed
shape: Add map to owned callback in data traits
1 parent 87da884 commit ac970a1

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

src/data_traits.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,37 @@ pub unsafe trait RawData: Sized {
3535
// This method is only used for debugging
3636
fn _data_slice(&self) -> Option<&[Self::Elem]>;
3737

38+
/// If `Self` is convertible to OwnedRepr, call the callback with self and pass the return
39+
/// value; else return `None`.
40+
#[doc(hidden)]
41+
fn map_if_owned<D: Dimension, C>(_array: ArrayBase<Self, D>, _cb: C) -> Option<C::Output>
42+
where
43+
C: IfOwnedCb<Self, D>
44+
{
45+
None
46+
}
47+
48+
#[doc(hidden)]
49+
fn try_into_owned<D>(self_: ArrayBase<Self, D>)
50+
-> Result<ArrayBase<OwnedRepr<Self::Elem>, D>, ArrayBase<Self, D>>
51+
where
52+
D: Dimension
53+
{
54+
Err(self_)
55+
}
56+
3857
private_decl! {}
3958
}
4059

60+
/// Helper trait that represents a "generic callback", in a way that closures can't.
61+
pub trait IfOwnedCb<S: RawData, D> {
62+
type Output;
63+
fn cb(self, array: ArrayBase<OwnedRepr<S::Elem>, D>) -> Self::Output
64+
where
65+
S: DataOwned,
66+
D: Dimension;
67+
}
68+
4169
/// Array representation trait.
4270
///
4371
/// For an array with writable elements.
@@ -192,6 +220,35 @@ unsafe impl<A> RawData for OwnedArcRepr<A> {
192220
fn _data_slice(&self) -> Option<&[A]> {
193221
Some(self.0.as_slice())
194222
}
223+
224+
fn map_if_owned<D: Dimension, C>(array: ArrayBase<Self, D>, _cb: C) -> Option<C::Output>
225+
where
226+
C: IfOwnedCb<Self, D>
227+
{
228+
Self::try_into_owned(array).ok().map(|array| _cb.cb(array))
229+
}
230+
231+
#[doc(hidden)]
232+
fn try_into_owned<D>(self_: ArrayBase<Self, D>)
233+
-> Result<ArrayBase<OwnedRepr<Self::Elem>, D>, ArrayBase<Self, D>>
234+
where
235+
D: Dimension
236+
{
237+
match Arc::try_unwrap(self_.data.0) {
238+
Ok(data) => Ok(ArrayBase {
239+
data,
240+
ptr: self_.ptr,
241+
dim: self_.dim,
242+
strides: self_.strides,
243+
}),
244+
Err(data) => Err(ArrayBase {
245+
data: OwnedArcRepr(data),
246+
ptr: self_.ptr,
247+
dim: self_.dim,
248+
strides: self_.strides,
249+
}),
250+
}
251+
}
195252
private_impl! {}
196253
}
197254

@@ -276,6 +333,22 @@ unsafe impl<A> RawData for OwnedRepr<A> {
276333
fn _data_slice(&self) -> Option<&[A]> {
277334
Some(self.as_slice())
278335
}
336+
337+
fn map_if_owned<D: Dimension, C>(array: ArrayBase<Self, D>, _cb: C) -> Option<C::Output>
338+
where
339+
C: IfOwnedCb<Self, D>
340+
{
341+
Some(_cb.cb(array))
342+
}
343+
344+
#[doc(hidden)]
345+
fn try_into_owned<D>(self_: ArrayBase<Self, D>)
346+
-> Result<ArrayBase<OwnedRepr<Self::Elem>, D>, ArrayBase<Self, D>>
347+
where
348+
D: Dimension
349+
{
350+
Ok(self_)
351+
}
279352
private_impl! {}
280353
}
281354

@@ -463,6 +536,30 @@ unsafe impl<'a, A> RawData for CowRepr<'a, A> {
463536
CowRepr::Owned(data) => data._data_slice(),
464537
}
465538
}
539+
540+
fn try_into_owned<D>(self_: ArrayBase<Self, D>)
541+
-> Result<ArrayBase<OwnedRepr<Self::Elem>, D>, ArrayBase<Self, D>>
542+
where
543+
D: Dimension
544+
{
545+
match self_.data {
546+
data @ CowRepr::View(_) => Err(
547+
ArrayBase {
548+
data,
549+
ptr: self_.ptr,
550+
dim: self_.dim,
551+
strides: self_.strides,
552+
}),
553+
CowRepr::Owned(data) => Ok(
554+
ArrayBase {
555+
data,
556+
ptr: self_.ptr,
557+
dim: self_.dim,
558+
strides: self_.strides,
559+
}),
560+
}
561+
}
562+
466563
private_impl! {}
467564
}
468565

0 commit comments

Comments
 (0)