@@ -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