diff --git a/src/impl_methods.rs b/src/impl_methods.rs
index 8d2b3cd3a..95a78312e 100644
--- a/src/impl_methods.rs
+++ b/src/impl_methods.rs
@@ -1884,10 +1884,84 @@ where
}
}
+ /// Transform the array into `shape`; any shape with the same number of
+ /// elements is accepted, but the source array must be contiguous.
+ ///
+ /// If an index ordering is not specified, the default is `RowMajor`.
+ /// The operation will only succeed if the array's memory layout is compatible with
+ /// the index ordering.
+ ///
+ /// Use `.to_shape()` instead for more flexible reshaping of arrays, which
+ /// allows copying elements if required.
+ ///
+ /// **Errors** if the shapes don't have the same number of elements.
+ /// **Errors** if order RowMajor is given but input is not c-contiguous.
+ /// **Errors** if order ColumnMajor is given but input is not f-contiguous.
+ ///
+ /// If shape is not given: use memory layout of incoming array. Row major arrays are
+ /// reshaped using row major index ordering, column major arrays with column major index
+ /// ordering.
+ ///
+ /// ```
+ /// use ndarray::{aview1, aview2};
+ /// use ndarray::Order;
+ ///
+ /// assert!(
+ /// aview1(&[1., 2., 3., 4.]).into_shape_with_order((2, 2)).unwrap()
+ /// == aview2(&[[1., 2.],
+ /// [3., 4.]])
+ /// );
+ ///
+ /// assert!(
+ /// aview1(&[1., 2., 3., 4.]).into_shape_with_order(((2, 2), Order::ColumnMajor)).unwrap()
+ /// == aview2(&[[1., 3.],
+ /// [2., 4.]])
+ /// );
+ /// ```
+ pub fn into_shape_with_order(self, shape: E) -> Result, ShapeError>
+ where
+ E: ShapeArg,
+ {
+ let (shape, order) = shape.into_shape_and_order();
+ self.into_shape_with_order_impl(shape, order.unwrap_or(Order::RowMajor))
+ }
+
+ fn into_shape_with_order_impl(self, shape: E, order: Order)
+ -> Result, ShapeError>
+ where
+ E: Dimension,
+ {
+ let shape = shape.into_dimension();
+ if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
+ return Err(error::incompatible_shapes(&self.dim, &shape));
+ }
+
+ // Check if contiguous, then we can change shape
+ unsafe {
+ // safe because arrays are contiguous and len is unchanged
+ match order {
+ Order::RowMajor if self.is_standard_layout() => {
+ Ok(self.with_strides_dim(shape.default_strides(), shape))
+ }
+ Order::ColumnMajor if self.raw_view().reversed_axes().is_standard_layout() => {
+ Ok(self.with_strides_dim(shape.fortran_strides(), shape))
+ }
+ _otherwise => Err(error::from_kind(error::ErrorKind::IncompatibleLayout))
+ }
+ }
+ }
+
/// Transform the array into `shape`; any shape with the same number of
/// elements is accepted, but the source array or view must be in standard
/// or column-major (Fortran) layout.
///
+ /// **Note** that `.into_shape()` "moves" elements differently depending on if the input array
+ /// is C-contig or F-contig, it follows the index order that corresponds to the memory order.
+ /// Prefer to use `.to_shape()` or `.into_shape_with_order()`.
+ ///
+ /// Because of this, the method is deprecated. That reshapes depend on memory order is not
+ /// intuitive.
+ ///
/// **Errors** if the shapes don't have the same number of elements.
/// **Errors** if the input array is not c- or f-contiguous.
///
@@ -1900,6 +1974,7 @@ where
/// [3., 4.]])
/// );
/// ```
+ #[deprecated = "Use `.into_shape_with_order()` or `.to_shape()`"]
pub fn into_shape(self, shape: E) -> Result, ShapeError>
where
E: IntoDimension,
@@ -1932,7 +2007,7 @@ where
self.into_shape_clone_order(shape, order)
}
- pub fn into_shape_clone_order(self, shape: E, order: Order)
+ fn into_shape_clone_order(self, shape: E, order: Order)
-> Result, ShapeError>
where
S: DataOwned,
@@ -2004,7 +2079,7 @@ where
A: Clone,
E: IntoDimension,
{
- return self.clone().into_shape_clone(shape).unwrap();
+ //return self.clone().into_shape_clone(shape).unwrap();
let shape = shape.into_dimension();
if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
panic!(
diff --git a/tests/reshape.rs b/tests/reshape.rs
index 21fe407ea..52bb6e908 100644
--- a/tests/reshape.rs
+++ b/tests/reshape.rs
@@ -230,3 +230,41 @@ fn to_shape_broadcast() {
}
}
}
+
+
+#[test]
+fn into_shape_with_order() {
+ // 1D -> C -> C
+ let data = [1, 2, 3, 4, 5, 6, 7, 8];
+ let v = aview1(&data);
+ let u = v.into_shape_with_order(((3, 3), Order::RowMajor));
+ assert!(u.is_err());
+
+ let u = v.into_shape_with_order(((2, 2, 2), Order::C));
+ assert!(u.is_ok());
+
+ let u = u.unwrap();
+ assert_eq!(u.shape(), &[2, 2, 2]);
+ assert_eq!(u, array![[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
+
+ let s = u.into_shape_with_order((4, 2)).unwrap();
+ assert_eq!(s.shape(), &[4, 2]);
+ assert_eq!(s, aview2(&[[1, 2], [3, 4], [5, 6], [7, 8]]));
+
+ // 1D -> F -> F
+ let data = [1, 2, 3, 4, 5, 6, 7, 8];
+ let v = aview1(&data);
+ let u = v.into_shape_with_order(((3, 3), Order::ColumnMajor));
+ assert!(u.is_err());
+
+ let u = v.into_shape_with_order(((2, 2, 2), Order::ColumnMajor));
+ assert!(u.is_ok());
+
+ let u = u.unwrap();
+ assert_eq!(u.shape(), &[2, 2, 2]);
+ assert_eq!(u, array![[[1, 5], [3, 7]], [[2, 6], [4, 8]]]);
+
+ let s = u.into_shape_with_order(((4, 2), Order::ColumnMajor)).unwrap();
+ assert_eq!(s.shape(), &[4, 2]);
+ assert_eq!(s, array![[1, 5], [2, 6], [3, 7], [4, 8]]);
+}