@@ -109,6 +109,15 @@ pub unsafe trait Data: RawData {
109109 Self :: Elem : Clone ,
110110 D : Dimension ;
111111
112+ /// Converts the array into `Array<A, D>` if this is possible without
113+ /// cloning the array elements. Otherwise, returns `self_` unchanged.
114+ #[ doc( hidden) ]
115+ fn try_into_owned_nocopy < D > (
116+ self_ : ArrayBase < Self , D > ,
117+ ) -> Result < ArrayBase < OwnedRepr < Self :: Elem > , D > , ArrayBase < Self , D > >
118+ where
119+ D : Dimension ;
120+
112121 /// Return a shared ownership (copy on write) array based on the existing one,
113122 /// cloning elements if necessary.
114123 #[ doc( hidden) ]
@@ -276,6 +285,27 @@ unsafe impl<A> Data for OwnedArcRepr<A> {
276285 }
277286 }
278287
288+ fn try_into_owned_nocopy < D > (
289+ self_ : ArrayBase < Self , D > ,
290+ ) -> Result < ArrayBase < OwnedRepr < Self :: Elem > , D > , ArrayBase < Self , D > >
291+ where
292+ D : Dimension ,
293+ {
294+ match Arc :: try_unwrap ( self_. data . 0 ) {
295+ Ok ( owned_data) => unsafe {
296+ // Safe because the data is equivalent.
297+ Ok ( ArrayBase :: from_data_ptr ( owned_data, self_. ptr )
298+ . with_strides_dim ( self_. strides , self_. dim ) )
299+ } ,
300+ Err ( arc_data) => unsafe {
301+ // Safe because the data is equivalent; we're just
302+ // reconstructing `self_`.
303+ Err ( ArrayBase :: from_data_ptr ( OwnedArcRepr ( arc_data) , self_. ptr )
304+ . with_strides_dim ( self_. strides , self_. dim ) )
305+ } ,
306+ }
307+ }
308+
279309 #[ allow( clippy:: wrong_self_convention) ]
280310 fn to_shared < D > ( self_ : & ArrayBase < Self , D > ) -> ArrayBase < OwnedArcRepr < Self :: Elem > , D >
281311 where
@@ -337,6 +367,16 @@ unsafe impl<A> Data for OwnedRepr<A> {
337367 {
338368 self_
339369 }
370+
371+ #[ inline]
372+ fn try_into_owned_nocopy < D > (
373+ self_ : ArrayBase < Self , D > ,
374+ ) -> Result < ArrayBase < Self , D > , ArrayBase < Self , D > >
375+ where
376+ D : Dimension ,
377+ {
378+ Ok ( self_)
379+ }
340380}
341381
342382unsafe impl < A > DataMut for OwnedRepr < A > { }
@@ -393,6 +433,15 @@ unsafe impl<'a, A> Data for ViewRepr<&'a A> {
393433 {
394434 self_. to_owned ( )
395435 }
436+
437+ fn try_into_owned_nocopy < D > (
438+ self_ : ArrayBase < Self , D > ,
439+ ) -> Result < ArrayBase < OwnedRepr < Self :: Elem > , D > , ArrayBase < Self , D > >
440+ where
441+ D : Dimension ,
442+ {
443+ Err ( self_)
444+ }
396445}
397446
398447unsafe impl < ' a , A > RawDataClone for ViewRepr < & ' a A > {
@@ -438,6 +487,15 @@ unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
438487 {
439488 self_. to_owned ( )
440489 }
490+
491+ fn try_into_owned_nocopy < D > (
492+ self_ : ArrayBase < Self , D > ,
493+ ) -> Result < ArrayBase < OwnedRepr < Self :: Elem > , D > , ArrayBase < Self , D > >
494+ where
495+ D : Dimension ,
496+ {
497+ Err ( self_)
498+ }
441499}
442500
443501unsafe impl < ' a , A > DataMut for ViewRepr < & ' a mut A > { }
@@ -609,6 +667,22 @@ unsafe impl<'a, A> Data for CowRepr<'a, A> {
609667 } ,
610668 }
611669 }
670+
671+ fn try_into_owned_nocopy < D > (
672+ self_ : ArrayBase < Self , D > ,
673+ ) -> Result < ArrayBase < OwnedRepr < Self :: Elem > , D > , ArrayBase < Self , D > >
674+ where
675+ D : Dimension ,
676+ {
677+ match self_. data {
678+ CowRepr :: View ( _) => Err ( self_) ,
679+ CowRepr :: Owned ( data) => unsafe {
680+ // safe because the data is equivalent so ptr, dims remain valid
681+ Ok ( ArrayBase :: from_data_ptr ( data, self_. ptr )
682+ . with_strides_dim ( self_. strides , self_. dim ) )
683+ } ,
684+ }
685+ }
612686}
613687
614688unsafe impl < ' a , A > DataMut for CowRepr < ' a , A > where A : Clone { }
0 commit comments