Skip to content

Commit d31c5e1

Browse files
committed
Move out array view methods
1 parent 5e64627 commit d31c5e1

File tree

2 files changed

+194
-174
lines changed

2 files changed

+194
-174
lines changed

src/impl_views.rs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
2+
use imp_prelude::*;
3+
use dimension::{self, stride_offset};
4+
use stride_error::StrideError;
5+
6+
use {
7+
ViewRepr,
8+
};
9+
10+
/// # Methods for Array Views
11+
///
12+
/// Methods for read-only array views `ArrayView<'a, A, D>`
13+
impl<'a, A> ArrayBase<ViewRepr<&'a A>, Ix> {
14+
/// Create a one-dimensional read-only array view of the data in `xs`.
15+
#[inline]
16+
pub fn from_slice(xs: &'a [A]) -> Self {
17+
ArrayView {
18+
data: ViewRepr::new(),
19+
ptr: xs.as_ptr() as *mut A,
20+
dim: xs.len(),
21+
strides: 1,
22+
}
23+
}
24+
}
25+
26+
impl<'a, A, D> ArrayBase<ViewRepr<&'a A>, D>
27+
where D: Dimension,
28+
{
29+
/// Create a read-only array view borrowing its data from a slice.
30+
///
31+
/// Checks whether `dim` and `strides` are compatible with the slice's
32+
/// length, returning an `Err` if not compatible.
33+
///
34+
/// ```
35+
/// use ndarray::ArrayView;
36+
/// use ndarray::arr3;
37+
///
38+
/// let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
39+
/// let a = ArrayView::from_slice_dim_stride((2, 3, 2),
40+
/// (1, 4, 2),
41+
/// &s).unwrap();
42+
///
43+
/// assert!(
44+
/// a == arr3(&[[[0, 2],
45+
/// [4, 6],
46+
/// [8, 10]],
47+
/// [[1, 3],
48+
/// [5, 7],
49+
/// [9, 11]]])
50+
/// );
51+
/// assert!(a.strides() == &[1, 4, 2]);
52+
/// ```
53+
pub fn from_slice_dim_stride(dim: D, strides: D, xs: &'a [A])
54+
-> Result<Self, StrideError>
55+
{
56+
dimension::can_index_slice(xs, &dim, &strides).map(|_| {
57+
unsafe {
58+
Self::new_(xs.as_ptr(), dim, strides)
59+
}
60+
})
61+
}
62+
63+
/// Split the array along `axis` and return one view strictly before the
64+
/// split and one view after the split.
65+
///
66+
/// **Panics** if `axis` or `index` is out of bounds.
67+
pub fn split_at(self, axis: Axis, index: Ix)
68+
-> (Self, Self)
69+
{
70+
// NOTE: Keep this in sync with the ArrayViewMut version
71+
let axis = axis.axis();
72+
assert!(index <= self.shape()[axis]);
73+
let left_ptr = self.ptr;
74+
let right_ptr = if index == self.shape()[axis] {
75+
self.ptr
76+
} else {
77+
let offset = stride_offset(index, self.strides.slice()[axis]);
78+
unsafe {
79+
self.ptr.offset(offset)
80+
}
81+
};
82+
83+
let mut dim_left = self.dim.clone();
84+
dim_left.slice_mut()[axis] = index;
85+
let left = unsafe {
86+
Self::new_(left_ptr, dim_left, self.strides.clone())
87+
};
88+
89+
let mut dim_right = self.dim;
90+
let right_len = dim_right.slice()[axis] - index;
91+
dim_right.slice_mut()[axis] = right_len;
92+
let right = unsafe {
93+
Self::new_(right_ptr, dim_right, self.strides)
94+
};
95+
96+
(left, right)
97+
}
98+
99+
}
100+
101+
/// Methods for read-write array views `ArrayViewMut<'a, A, D>`
102+
impl<'a, A> ArrayBase<ViewRepr<&'a mut A>, Ix> {
103+
/// Create a one-dimensional read-write array view of the data in `xs`.
104+
#[inline]
105+
pub fn from_slice(xs: &'a mut [A]) -> Self {
106+
ArrayViewMut {
107+
data: ViewRepr::new(),
108+
ptr: xs.as_mut_ptr(),
109+
dim: xs.len(),
110+
strides: 1,
111+
}
112+
}
113+
}
114+
115+
impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D>
116+
where D: Dimension,
117+
{
118+
/// Create a read-write array view borrowing its data from a slice.
119+
///
120+
/// Checks whether `dim` and `strides` are compatible with the slice's
121+
/// length, returning an `Err` if not compatible.
122+
///
123+
/// ```
124+
/// use ndarray::ArrayViewMut;
125+
/// use ndarray::arr3;
126+
///
127+
/// let mut s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
128+
/// let mut a = ArrayViewMut::from_slice_dim_stride((2, 3, 2),
129+
/// (1, 4, 2),
130+
/// &mut s).unwrap();
131+
///
132+
/// a[[0, 0, 0]] = 1;
133+
/// assert!(
134+
/// a == arr3(&[[[1, 2],
135+
/// [4, 6],
136+
/// [8, 10]],
137+
/// [[1, 3],
138+
/// [5, 7],
139+
/// [9, 11]]])
140+
/// );
141+
/// assert!(a.strides() == &[1, 4, 2]);
142+
/// ```
143+
pub fn from_slice_dim_stride(dim: D, strides: D, xs: &'a mut [A])
144+
-> Result<Self, StrideError>
145+
{
146+
dimension::can_index_slice(xs, &dim, &strides).map(|_| {
147+
unsafe {
148+
Self::new_(xs.as_mut_ptr(), dim, strides)
149+
}
150+
})
151+
}
152+
153+
/// Split the array along `axis` and return one mutable view strictly
154+
/// before the split and one mutable view after the split.
155+
///
156+
/// **Panics** if `axis` or `index` is out of bounds.
157+
pub fn split_at(self, axis: Axis, index: Ix)
158+
-> (Self, Self)
159+
{
160+
// NOTE: Keep this in sync with the ArrayView version
161+
let axis = axis.axis();
162+
assert!(index <= self.shape()[axis]);
163+
let left_ptr = self.ptr;
164+
let right_ptr = if index == self.shape()[axis] {
165+
self.ptr
166+
}
167+
else {
168+
let offset = stride_offset(index, self.strides.slice()[axis]);
169+
unsafe {
170+
self.ptr.offset(offset)
171+
}
172+
};
173+
174+
let mut dim_left = self.dim.clone();
175+
dim_left.slice_mut()[axis] = index;
176+
let left = unsafe {
177+
Self::new_(left_ptr, dim_left, self.strides.clone())
178+
};
179+
180+
let mut dim_right = self.dim;
181+
let right_len = dim_right.slice()[axis] - index;
182+
dim_right.slice_mut()[axis] = right_len;
183+
let right = unsafe {
184+
Self::new_(right_ptr, dim_right, self.strides)
185+
};
186+
187+
(left, right)
188+
}
189+
190+
}
191+

0 commit comments

Comments
 (0)