@@ -109,6 +109,15 @@ pub unsafe trait Data: RawData {
109
109
Self :: Elem : Clone ,
110
110
D : Dimension ;
111
111
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
+
112
121
/// Return a shared ownership (copy on write) array based on the existing one,
113
122
/// cloning elements if necessary.
114
123
#[ doc( hidden) ]
@@ -276,6 +285,27 @@ unsafe impl<A> Data for OwnedArcRepr<A> {
276
285
}
277
286
}
278
287
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
+
279
309
#[ allow( clippy:: wrong_self_convention) ]
280
310
fn to_shared < D > ( self_ : & ArrayBase < Self , D > ) -> ArrayBase < OwnedArcRepr < Self :: Elem > , D >
281
311
where
@@ -337,6 +367,16 @@ unsafe impl<A> Data for OwnedRepr<A> {
337
367
{
338
368
self_
339
369
}
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
+ }
340
380
}
341
381
342
382
unsafe impl < A > DataMut for OwnedRepr < A > { }
@@ -393,6 +433,15 @@ unsafe impl<'a, A> Data for ViewRepr<&'a A> {
393
433
{
394
434
self_. to_owned ( )
395
435
}
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
+ }
396
445
}
397
446
398
447
unsafe impl < ' a , A > RawDataClone for ViewRepr < & ' a A > {
@@ -438,6 +487,15 @@ unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
438
487
{
439
488
self_. to_owned ( )
440
489
}
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
+ }
441
499
}
442
500
443
501
unsafe impl < ' a , A > DataMut for ViewRepr < & ' a mut A > { }
@@ -609,6 +667,22 @@ unsafe impl<'a, A> Data for CowRepr<'a, A> {
609
667
} ,
610
668
}
611
669
}
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
+ }
612
686
}
613
687
614
688
unsafe impl < ' a , A > DataMut for CowRepr < ' a , A > where A : Clone { }
0 commit comments