Skip to content

Commit 014290c

Browse files
committed
WIP on into_shape_clone
1 parent fc765c1 commit 014290c

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

src/impl_methods.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)