@@ -1929,28 +1929,48 @@ where
19291929 {
19301930 let ( shape, order) = shape. into_shape_and_order ( ) ;
19311931 let order = order. unwrap_or ( Order :: RowMajor ) ;
1932+ self . into_shape_clone_order ( shape, order)
1933+ }
19321934
1933- if size_of_shape_checked ( & shape) != Ok ( self . dim . size ( ) ) {
1935+ pub fn into_shape_clone_order < E > ( self , shape : E , order : Order )
1936+ -> Result < ArrayBase < S , E > , ShapeError >
1937+ where
1938+ S : DataOwned ,
1939+ A : Clone ,
1940+ E : Dimension ,
1941+ {
1942+ let len = self . dim . size ( ) ;
1943+ if size_of_shape_checked ( & shape) != Ok ( len) {
19341944 return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
19351945 }
1936- let layout = self . layout_impl ( ) ;
19371946
1938- unsafe {
1939- if layout. is ( Layout :: CORDER ) && order == Order :: RowMajor {
1940- // safe because arrays are contiguous and len is unchanged
1941- Ok ( self . with_strides_dim ( shape. default_strides ( ) , shape) )
1942- } else if layout. is ( Layout :: FORDER ) && order == Order :: ColumnMajor {
1943- // safe because arrays are contiguous and len is unchanged
1944- Ok ( self . with_strides_dim ( shape. fortran_strides ( ) , shape) )
1945- } else {
1946- let ( shape, view) = match order {
1947- Order :: RowMajor => ( shape. set_f ( false ) , self . view ( ) ) ,
1948- Order :: ColumnMajor => ( shape. set_f ( true ) , self . t ( ) ) ,
1949- } ;
1947+ // Safe because the array and new shape is empty.
1948+ if len == 0 {
1949+ unsafe {
1950+ return Ok ( self . with_strides_dim ( shape. default_strides ( ) , shape) ) ;
1951+ }
1952+ }
19501953
1951- Ok ( ArrayBase :: from_shape_trusted_iter_unchecked (
1952- shape, view. into_iter ( ) , A :: clone) )
1954+ // Try to reshape the array's current data
1955+ match reshape_dim ( & self . dim , & self . strides , & shape, order) {
1956+ Ok ( to_strides) => unsafe {
1957+ return Ok ( self . with_strides_dim ( to_strides, shape) ) ;
1958+ }
1959+ Err ( err) if err. kind ( ) == ErrorKind :: IncompatibleShape => {
1960+ return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
19531961 }
1962+ _otherwise => { }
1963+ }
1964+
1965+ // otherwise, clone and allocate a new array
1966+ unsafe {
1967+ let ( shape, view) = match order {
1968+ Order :: RowMajor => ( shape. set_f ( false ) , self . view ( ) ) ,
1969+ Order :: ColumnMajor => ( shape. set_f ( true ) , self . t ( ) ) ,
1970+ } ;
1971+
1972+ Ok ( ArrayBase :: from_shape_trusted_iter_unchecked (
1973+ shape, view. into_iter ( ) , A :: clone) )
19541974 }
19551975 }
19561976
@@ -1984,6 +2004,7 @@ where
19842004 A : Clone ,
19852005 E : IntoDimension ,
19862006 {
2007+ return self . clone ( ) . into_shape_clone ( shape) . unwrap ( ) ;
19872008 let shape = shape. into_dimension ( ) ;
19882009 if size_of_shape_checked ( & shape) != Ok ( self . dim . size ( ) ) {
19892010 panic ! (
0 commit comments