@@ -242,11 +242,9 @@ where
242242 S : DataOwned ,
243243 {
244244 let data = self . data . into_shared ( ) ;
245- ArrayBase {
246- data,
247- ptr : self . ptr ,
248- dim : self . dim ,
249- strides : self . strides ,
245+ // safe because: equivalent unmoved data, ptr and dims remain valid
246+ unsafe {
247+ ArrayBase :: from_data_ptr ( data, self . ptr ) . with_strides_dim ( self . strides , self . dim )
250248 }
251249 }
252250
@@ -434,11 +432,9 @@ where
434432 * new_s = * s;
435433 } ) ;
436434
437- ArrayBase {
438- ptr : self . ptr ,
439- data : self . data ,
440- dim : new_dim,
441- strides : new_strides,
435+ // safe because new dimension, strides allow access to a subset of old data
436+ unsafe {
437+ self . with_strides_dim ( new_strides, new_dim)
442438 }
443439 }
444440
@@ -757,11 +753,9 @@ where
757753 self . collapse_axis ( axis, index) ;
758754 let dim = self . dim . remove_axis ( axis) ;
759755 let strides = self . strides . remove_axis ( axis) ;
760- ArrayBase {
761- ptr : self . ptr ,
762- data : self . data ,
763- dim,
764- strides,
756+ // safe because new dimension, strides allow access to a subset of old data
757+ unsafe {
758+ self . with_strides_dim ( strides, dim)
765759 }
766760 }
767761
@@ -1244,11 +1238,9 @@ where
12441238 /// Return the diagonal as a one-dimensional array.
12451239 pub fn into_diag ( self ) -> ArrayBase < S , Ix1 > {
12461240 let ( len, stride) = self . diag_params ( ) ;
1247- ArrayBase {
1248- data : self . data ,
1249- ptr : self . ptr ,
1250- dim : Ix1 ( len) ,
1251- strides : Ix1 ( stride as Ix ) ,
1241+ // safe because new len stride allows access to a subset of the current elements
1242+ unsafe {
1243+ self . with_strides_dim ( Ix1 ( stride as Ix ) , Ix1 ( len) )
12521244 }
12531245 }
12541246
@@ -1498,22 +1490,15 @@ where
14981490 return Err ( error:: incompatible_shapes ( & self . dim , & shape) ) ;
14991491 }
15001492 // Check if contiguous, if not => copy all, else just adapt strides
1501- if self . is_standard_layout ( ) {
1502- Ok ( ArrayBase {
1503- data : self . data ,
1504- ptr : self . ptr ,
1505- strides : shape. default_strides ( ) ,
1506- dim : shape,
1507- } )
1508- } else if self . ndim ( ) > 1 && self . raw_view ( ) . reversed_axes ( ) . is_standard_layout ( ) {
1509- Ok ( ArrayBase {
1510- data : self . data ,
1511- ptr : self . ptr ,
1512- strides : shape. fortran_strides ( ) ,
1513- dim : shape,
1514- } )
1515- } else {
1516- Err ( error:: from_kind ( error:: ErrorKind :: IncompatibleLayout ) )
1493+ unsafe {
1494+ // safe because arrays are contiguous and len is unchanged
1495+ if self . is_standard_layout ( ) {
1496+ Ok ( self . with_strides_dim ( shape. default_strides ( ) , shape) )
1497+ } else if self . ndim ( ) > 1 && self . raw_view ( ) . reversed_axes ( ) . is_standard_layout ( ) {
1498+ Ok ( self . with_strides_dim ( shape. fortran_strides ( ) , shape) )
1499+ } else {
1500+ Err ( error:: from_kind ( error:: ErrorKind :: IncompatibleLayout ) )
1501+ }
15171502 }
15181503 }
15191504
@@ -1554,11 +1539,9 @@ where
15541539 // Check if contiguous, if not => copy all, else just adapt strides
15551540 if self . is_standard_layout ( ) {
15561541 let cl = self . clone ( ) ;
1557- ArrayBase {
1558- data : cl. data ,
1559- ptr : cl. ptr ,
1560- strides : shape. default_strides ( ) ,
1561- dim : shape,
1542+ // safe because array is contiguous and shape has equal number of elements
1543+ unsafe {
1544+ cl. with_strides_dim ( shape. default_strides ( ) , shape)
15621545 }
15631546 } else {
15641547 let v = self . iter ( ) . cloned ( ) . collect :: < Vec < A > > ( ) ;
@@ -1576,11 +1559,10 @@ where
15761559 /// [3, 4]]).into_dyn();
15771560 /// ```
15781561 pub fn into_dyn ( self ) -> ArrayBase < S , IxDyn > {
1579- ArrayBase {
1580- data : self . data ,
1581- ptr : self . ptr ,
1582- dim : self . dim . into_dyn ( ) ,
1583- strides : self . strides . into_dyn ( ) ,
1562+ // safe because new dims equivalent
1563+ unsafe {
1564+ ArrayBase :: from_data_ptr ( self . data , self . ptr )
1565+ . with_strides_dim ( self . strides . into_dyn ( ) , self . dim . into_dyn ( ) )
15841566 }
15851567 }
15861568
@@ -1604,27 +1586,19 @@ where
16041586 where
16051587 D2 : Dimension ,
16061588 {
1607- if D :: NDIM == D2 :: NDIM {
1608- // safe because D == D2
1609- unsafe {
1589+ unsafe {
1590+ if D :: NDIM == D2 :: NDIM {
1591+ // safe because D == D2
16101592 let dim = unlimited_transmute :: < D , D2 > ( self . dim ) ;
16111593 let strides = unlimited_transmute :: < D , D2 > ( self . strides ) ;
1612- return Ok ( ArrayBase {
1613- data : self . data ,
1614- ptr : self . ptr ,
1615- dim,
1616- strides,
1617- } ) ;
1618- }
1619- } else if D :: NDIM == None || D2 :: NDIM == None { // one is dynamic dim
1620- if let Some ( dim) = D2 :: from_dimension ( & self . dim ) {
1621- if let Some ( strides) = D2 :: from_dimension ( & self . strides ) {
1622- return Ok ( ArrayBase {
1623- data : self . data ,
1624- ptr : self . ptr ,
1625- dim,
1626- strides,
1627- } ) ;
1594+ return Ok ( ArrayBase :: from_data_ptr ( self . data , self . ptr )
1595+ . with_strides_dim ( strides, dim) ) ;
1596+ } else if D :: NDIM == None || D2 :: NDIM == None { // one is dynamic dim
1597+ // safe because dim, strides are equivalent under a different type
1598+ if let Some ( dim) = D2 :: from_dimension ( & self . dim ) {
1599+ if let Some ( strides) = D2 :: from_dimension ( & self . strides ) {
1600+ return Ok ( self . with_strides_dim ( strides, dim) ) ;
1601+ }
16281602 }
16291603 }
16301604 }
@@ -1792,10 +1766,9 @@ where
17921766 new_strides[ new_axis] = strides[ axis] ;
17931767 }
17941768 }
1795- ArrayBase {
1796- dim : new_dim,
1797- strides : new_strides,
1798- ..self
1769+ // safe because axis invariants are checked above; they are a permutation of the old
1770+ unsafe {
1771+ self . with_strides_dim ( new_strides, new_dim)
17991772 }
18001773 }
18011774
@@ -1915,17 +1888,11 @@ where
19151888 /// ***Panics*** if the axis is out of bounds.
19161889 pub fn insert_axis ( self , axis : Axis ) -> ArrayBase < S , D :: Larger > {
19171890 assert ! ( axis. index( ) <= self . ndim( ) ) ;
1918- let ArrayBase {
1919- ptr,
1920- data,
1921- dim,
1922- strides,
1923- } = self ;
1924- ArrayBase {
1925- ptr,
1926- data,
1927- dim : dim. insert_axis ( axis) ,
1928- strides : strides. insert_axis ( axis) ,
1891+ // safe because a new axis of length one does not affect memory layout
1892+ unsafe {
1893+ let strides = self . strides . insert_axis ( axis) ;
1894+ let dim = self . dim . insert_axis ( axis) ;
1895+ self . with_strides_dim ( strides, dim)
19291896 }
19301897 }
19311898
@@ -1942,7 +1909,7 @@ where
19421909 self . index_axis_move ( axis, 0 )
19431910 }
19441911
1945- fn pointer_is_inbounds ( & self ) -> bool {
1912+ pub ( crate ) fn pointer_is_inbounds ( & self ) -> bool {
19461913 match self . data . _data_slice ( ) {
19471914 None => {
19481915 // special case for non-owned views
0 commit comments