@@ -23,6 +23,7 @@ use crate::dimension::{
2323 offset_from_ptr_to_memory, size_of_shape_checked, stride_offset, Axes ,
2424} ;
2525use crate :: dimension:: broadcast:: co_broadcast;
26+ use crate :: dimension:: reshape_dim;
2627use crate :: error:: { self , ErrorKind , ShapeError , from_kind} ;
2728use crate :: math_cell:: MathCell ;
2829use crate :: itertools:: zip;
@@ -1641,26 +1642,37 @@ where
16411642 A : Clone ,
16421643 S : Data ,
16431644 {
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) {
16451647 return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
16461648 }
1647- let layout = self . layout_impl ( ) ;
16481649
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) ) ) ;
16631661 }
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) ) )
16641676 }
16651677 }
16661678
0 commit comments