@@ -23,11 +23,11 @@ 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;
29
30
use crate :: AxisDescription ;
30
- use crate :: Layout ;
31
31
use crate :: order:: Order ;
32
32
use crate :: shape_builder:: ShapeArg ;
33
33
use crate :: zip:: { IntoNdProducer , Zip } ;
@@ -1641,27 +1641,38 @@ where
1641
1641
A : Clone ,
1642
1642
S : Data ,
1643
1643
{
1644
- if size_of_shape_checked ( & shape) != Ok ( self . dim . size ( ) ) {
1644
+ let len = self . dim . size ( ) ;
1645
+ if size_of_shape_checked ( & shape) != Ok ( len) {
1645
1646
return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
1646
1647
}
1647
- let layout = self . layout_impl ( ) ;
1648
1648
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) ) )
1649
+ // Create a view if the length is 0, safe because the array and new shape is empty.
1650
+ if len == 0 {
1651
+ unsafe {
1652
+ return Ok ( CowArray :: from ( ArrayView :: from_shape_ptr ( shape, self . as_ptr ( ) ) ) ) ;
1663
1653
}
1664
1654
}
1655
+
1656
+ // Try to reshape the array as a view into the existing data
1657
+ match reshape_dim ( & self . dim , & self . strides , & shape, order) {
1658
+ Ok ( to_strides) => unsafe {
1659
+ return Ok ( CowArray :: from ( ArrayView :: new ( self . ptr , shape, to_strides) ) ) ;
1660
+ }
1661
+ Err ( err) if err. kind ( ) == ErrorKind :: IncompatibleShape => {
1662
+ return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
1663
+ }
1664
+ _otherwise => { }
1665
+ }
1666
+
1667
+ // otherwise create a new array and copy the elements
1668
+ unsafe {
1669
+ let ( shape, view) = match order {
1670
+ Order :: RowMajor => ( shape. set_f ( false ) , self . view ( ) ) ,
1671
+ Order :: ColumnMajor => ( shape. set_f ( true ) , self . t ( ) ) ,
1672
+ } ;
1673
+ Ok ( CowArray :: from ( Array :: from_shape_trusted_iter_unchecked (
1674
+ shape, view. into_iter ( ) , A :: clone) ) )
1675
+ }
1665
1676
}
1666
1677
1667
1678
/// Transform the array into `shape`; any shape with the same number of
0 commit comments