ferray_core/array/
view_mut.rs1use crate::dimension::Dimension;
4use crate::dtype::Element;
5use crate::layout::MemoryLayout;
6
7use super::ArrayFlags;
8use super::owned::Array;
9
10pub struct ArrayViewMut<'a, T: Element, D: Dimension> {
15 pub(crate) inner: ndarray::ArrayViewMut<'a, T, D::NdarrayDim>,
16 pub(crate) dim: D,
17}
18
19impl<'a, T: Element, D: Dimension> ArrayViewMut<'a, T, D> {
20 pub(crate) fn from_ndarray(inner: ndarray::ArrayViewMut<'a, T, D::NdarrayDim>) -> Self {
22 let dim = D::from_ndarray_dim(&inner.raw_dim());
23 Self { inner, dim }
24 }
25
26 #[inline]
28 pub fn shape(&self) -> &[usize] {
29 self.inner.shape()
30 }
31
32 #[inline]
34 pub fn ndim(&self) -> usize {
35 self.dim.ndim()
36 }
37
38 #[inline]
40 pub fn size(&self) -> usize {
41 self.inner.len()
42 }
43
44 #[inline]
46 pub fn is_empty(&self) -> bool {
47 self.inner.is_empty()
48 }
49
50 #[inline]
52 pub fn strides(&self) -> &[isize] {
53 self.inner.strides()
54 }
55
56 #[inline]
58 pub fn as_ptr(&self) -> *const T {
59 self.inner.as_ptr()
60 }
61
62 #[inline]
64 pub fn as_mut_ptr(&mut self) -> *mut T {
65 self.inner.as_mut_ptr()
66 }
67
68 pub fn as_slice(&self) -> Option<&[T]> {
70 self.inner.as_slice()
71 }
72
73 pub fn as_slice_mut(&mut self) -> Option<&mut [T]> {
75 self.inner.as_slice_mut()
76 }
77
78 pub fn layout(&self) -> MemoryLayout {
80 if self.inner.is_standard_layout() {
81 MemoryLayout::C
82 } else {
83 let shape = self.dim.as_slice();
84 let strides: Vec<isize> = self.inner.strides().to_vec();
85 crate::layout::detect_layout(shape, &strides)
86 }
87 }
88
89 #[inline]
91 pub fn dim(&self) -> &D {
92 &self.dim
93 }
94
95 pub fn flags(&self) -> ArrayFlags {
97 let layout = self.layout();
98 ArrayFlags {
99 c_contiguous: layout.is_c_contiguous(),
100 f_contiguous: layout.is_f_contiguous(),
101 owndata: false,
102 writeable: true,
103 }
104 }
105}
106
107impl<T: Element, D: Dimension> Array<T, D> {
109 pub fn view_mut(&mut self) -> ArrayViewMut<'_, T, D> {
111 ArrayViewMut::from_ndarray(self.inner.view_mut())
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::dimension::Ix1;
119
120 #[test]
121 fn view_mut_from_owned() {
122 let mut arr = Array::<f64, Ix1>::from_vec(Ix1::new([3]), vec![1.0, 2.0, 3.0]).unwrap();
123 let v = arr.view_mut();
124 assert_eq!(v.shape(), &[3]);
125 assert!(v.flags().writeable);
126 assert!(!v.flags().owndata);
127 }
128
129 #[test]
130 fn view_mut_modify() {
131 let mut arr = Array::<f64, Ix1>::from_vec(Ix1::new([3]), vec![1.0, 2.0, 3.0]).unwrap();
132 {
133 let mut v = arr.view_mut();
134 if let Some(s) = v.as_slice_mut() {
135 s[0] = 99.0;
136 }
137 }
138 assert_eq!(arr.as_slice().unwrap()[0], 99.0);
139 }
140}