Skip to content

Commit

Permalink
WIP on into_shape_clone
Browse files Browse the repository at this point in the history
  • Loading branch information
bluss committed Jul 25, 2023
1 parent fc765c1 commit 014290c
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions src/impl_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1929,28 +1929,48 @@ where
{
let (shape, order) = shape.into_shape_and_order();
let order = order.unwrap_or(Order::RowMajor);
self.into_shape_clone_order(shape, order)
}

if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
pub fn into_shape_clone_order<E>(self, shape: E, order: Order)
-> Result<ArrayBase<S, E>, ShapeError>
where
S: DataOwned,
A: Clone,
E: Dimension,
{
let len = self.dim.size();
if size_of_shape_checked(&shape) != Ok(len) {
return Err(error::incompatible_shapes(&self.dim, &shape));
}
let layout = self.layout_impl();

unsafe {
if layout.is(Layout::CORDER) && order == Order::RowMajor {
// safe because arrays are contiguous and len is unchanged
Ok(self.with_strides_dim(shape.default_strides(), shape))
} else if layout.is(Layout::FORDER) && order == Order::ColumnMajor {
// safe because arrays are contiguous and len is unchanged
Ok(self.with_strides_dim(shape.fortran_strides(), shape))
} else {
let (shape, view) = match order {
Order::RowMajor => (shape.set_f(false), self.view()),
Order::ColumnMajor => (shape.set_f(true), self.t()),
};
// Safe because the array and new shape is empty.
if len == 0 {
unsafe {
return Ok(self.with_strides_dim(shape.default_strides(), shape));
}
}

Ok(ArrayBase::from_shape_trusted_iter_unchecked(
shape, view.into_iter(), A::clone))
// Try to reshape the array's current data
match reshape_dim(&self.dim, &self.strides, &shape, order) {
Ok(to_strides) => unsafe {
return Ok(self.with_strides_dim(to_strides, shape));
}
Err(err) if err.kind() == ErrorKind::IncompatibleShape => {
return Err(error::incompatible_shapes(&self.dim, &shape));
}
_otherwise => { }
}

// otherwise, clone and allocate a new array
unsafe {
let (shape, view) = match order {
Order::RowMajor => (shape.set_f(false), self.view()),
Order::ColumnMajor => (shape.set_f(true), self.t()),
};

Ok(ArrayBase::from_shape_trusted_iter_unchecked(
shape, view.into_iter(), A::clone))
}
}

Expand Down Expand Up @@ -1984,6 +2004,7 @@ where
A: Clone,
E: IntoDimension,
{
return self.clone().into_shape_clone(shape).unwrap();
let shape = shape.into_dimension();
if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
panic!(
Expand Down

0 comments on commit 014290c

Please sign in to comment.