@@ -23,6 +23,7 @@ use crate::dimension::{
23
23
offset_from_ptr_to_memory, size_of_shape_checked, stride_offset, Axes ,
24
24
} ;
25
25
use crate :: dimension:: broadcast:: co_broadcast;
26
+ use crate :: dimension:: reshape_dim;
26
27
use crate :: error:: { self , ErrorKind , ShapeError , from_kind} ;
27
28
use crate :: math_cell:: MathCell ;
28
29
use crate :: itertools:: zip;
@@ -1641,26 +1642,37 @@ where
1641
1642
A : Clone ,
1642
1643
S : Data ,
1643
1644
{
1644
- if size_of_shape_checked ( & shape) != Ok ( self . dim . size ( ) ) {
1645
+ let len = self . dim . size ( ) ;
1646
+ if size_of_shape_checked ( & shape) != Ok ( len) {
1645
1647
return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
1646
1648
}
1647
- let layout = self . layout_impl ( ) ;
1648
1649
1649
- unsafe {
1650
- if layout. is ( Layout :: CORDER ) && order == Order :: RowMajor {
1651
- let strides = shape. default_strides ( ) ;
1652
- Ok ( CowArray :: from ( ArrayView :: new ( self . ptr , shape, strides) ) )
1653
- } else if layout. is ( Layout :: FORDER ) && order == Order :: ColumnMajor {
1654
- let strides = shape. fortran_strides ( ) ;
1655
- Ok ( CowArray :: from ( ArrayView :: new ( self . ptr , shape, strides) ) )
1656
- } else {
1657
- let ( shape, view) = match order {
1658
- Order :: RowMajor => ( shape. set_f ( false ) , self . view ( ) ) ,
1659
- Order :: ColumnMajor => ( shape. set_f ( true ) , self . t ( ) ) ,
1660
- } ;
1661
- Ok ( CowArray :: from ( Array :: from_shape_trusted_iter_unchecked (
1662
- shape, view. into_iter ( ) , A :: clone) ) )
1650
+ // Create a view if the length is 0, safe because the array and new shape is empty.
1651
+ if len == 0 {
1652
+ unsafe {
1653
+ return Ok ( CowArray :: from ( ArrayView :: from_shape_ptr ( shape, self . as_ptr ( ) ) ) ) ;
1654
+ }
1655
+ }
1656
+
1657
+ // Try to reshape the array as a view into the existing data
1658
+ match reshape_dim ( & self . dim , & self . strides , & shape, order) {
1659
+ Ok ( to_strides) => unsafe {
1660
+ return Ok ( CowArray :: from ( ArrayView :: new ( self . ptr , shape, to_strides) ) ) ;
1663
1661
}
1662
+ Err ( err) if err. kind ( ) == ErrorKind :: IncompatibleShape => {
1663
+ return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
1664
+ }
1665
+ _otherwise => { }
1666
+ }
1667
+
1668
+ // otherwise create a new array and copy the elements
1669
+ unsafe {
1670
+ let ( shape, view) = match order {
1671
+ Order :: RowMajor => ( shape. set_f ( false ) , self . view ( ) ) ,
1672
+ Order :: ColumnMajor => ( shape. set_f ( true ) , self . t ( ) ) ,
1673
+ } ;
1674
+ Ok ( CowArray :: from ( Array :: from_shape_trusted_iter_unchecked (
1675
+ shape, view. into_iter ( ) , A :: clone) ) )
1664
1676
}
1665
1677
}
1666
1678
0 commit comments