use core::marker::PhantomData;
use ndarray::{ArrayBase, ArrayViewMut, Dimension, RawArrayViewMut, RawDataMut};
pub(crate) struct UnsafeSharedRef<'a, A, D> {
view: RawArrayViewMut<A, D>,
_marker: PhantomData<&'a mut A>,
}
unsafe impl<A: Send, D: Sync> Sync for UnsafeSharedRef<'_, A, D> {}
impl<'a, A, D: Dimension> UnsafeSharedRef<'a, A, D> {
pub fn new<S: RawDataMut<Elem = A>>(data: &'a mut ArrayBase<S, D>) -> Self {
Self {
view: data.raw_view_mut(),
_marker: PhantomData,
}
}
pub unsafe fn get(&self) -> ArrayViewMut<'a, A, D> {
unsafe { self.view.clone().deref_into_view_mut() }
}
}
#[cfg(test)]
mod tests {
use super::*;
use ndarray::Array4;
#[test]
fn handles_stay_valid_while_another_is_alive() {
let mut output = Array4::<f32>::zeros((2, 1, 2, 2));
{
let shared = UnsafeSharedRef::new(&mut output);
let mut first = unsafe { shared.get() };
let mut second = unsafe { shared.get() };
second[(1, 0, 1, 1)] = 2.0;
first[(0, 0, 0, 0)] = 1.0;
}
assert_eq!(output[(0, 0, 0, 0)], 1.0);
assert_eq!(output[(1, 0, 1, 1)], 2.0);
}
}