Skip to content

Commit

Permalink
FEAT: Add methods .cell_view() and .into_cell_view()
Browse files Browse the repository at this point in the history
  • Loading branch information
bluss committed Dec 29, 2020
1 parent 79392bb commit ccfedf0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/impl_methods.rs
Expand Up @@ -6,6 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cell::Cell;
use std::ptr as std_ptr;
use std::slice;

Expand Down Expand Up @@ -151,6 +152,20 @@ where
unsafe { ArrayViewMut::new(self.ptr, self.dim.clone(), self.strides.clone()) }
}

/// Return a shared view of the array with elements as if they were embedded in cells.
///
/// The cell view requires a mutable borrow of the array. Once borrowed the
/// cell view itself can be copied and accessed without exclusivity.
///
/// The view acts "as if" the elements are temporarily in cells, and elements
/// can be changed through shared references using the regular cell methods.
pub fn cell_view(&mut self) -> ArrayView<'_, Cell<A>, D>
where
S: DataMut,
{
self.view_mut().into_cell_view()
}

/// Return an uniquely owned copy of the array.
///
/// If the input array is contiguous and its strides are positive, then the
Expand Down
16 changes: 16 additions & 0 deletions src/impl_views/conversions.rs
Expand Up @@ -6,6 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cell::Cell;
use std::slice;

use crate::imp_prelude::*;
Expand Down Expand Up @@ -117,6 +118,21 @@ where
pub fn into_slice(self) -> Option<&'a mut [A]> {
self.try_into_slice().ok()
}

/// Return a shared view of the array with elements as if they were embedded in cells.
///
/// The cell view itself can be copied and accessed without exclusivity.
///
/// The view acts "as if" the elements are temporarily in cells, and elements
/// can be changed through shared references using the regular cell methods.
pub fn into_cell_view(self) -> ArrayView<'a, Cell<A>, D> {
// safety: valid because
// A and Cell<A> have the same representation
// &'a mut T is interchangeable with &'a Cell<T> -- see method Cell::from_mut
unsafe {
self.into_raw_view_mut().cast::<Cell<A>>().deref_into_view()
}
}
}

/// Private array view methods
Expand Down
16 changes: 16 additions & 0 deletions tests/views.rs
@@ -0,0 +1,16 @@
use ndarray::prelude::*;
use ndarray::Zip;

#[test]
fn cell_view() {
let mut a = Array::from_shape_fn((10, 5), |(i, j)| (i * j) as f32);
let answer = &a + 1.;

{
let cv1 = a.cell_view();
let cv2 = cv1;

Zip::from(cv1).and(cv2).apply(|a, b| a.set(b.get() + 1.));
}
assert_eq!(a, answer);
}

0 comments on commit ccfedf0

Please sign in to comment.