Skip to content

Commit d70e67a

Browse files
committed
Add field names to Slice and SliceOrIndex::Slice
Also rename .step() to .step_by().
1 parent 2d4ceab commit d70e67a

File tree

4 files changed

+113
-54
lines changed

4 files changed

+113
-54
lines changed

src/impl_methods.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
269269
let mut new_strides = Do::zero_index_with_ndim(out_ndim);
270270
izip!(self.dim.slice(), self.strides.slice(), indices)
271271
.filter_map(|(d, s, slice_or_index)| match slice_or_index {
272-
&SliceOrIndex::Slice(..) => Some((d, s)),
272+
&SliceOrIndex::Slice {..} => Some((d, s)),
273273
&SliceOrIndex::Index(_) => None,
274274
})
275275
.zip(izip!(new_dim.slice_mut(), new_strides.slice_mut()))
@@ -307,8 +307,8 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
307307
.iter()
308308
.enumerate()
309309
.for_each(|(axis, slice_or_index)| match slice_or_index {
310-
&SliceOrIndex::Slice(start, end, step) => {
311-
self.slice_axis_inplace(Axis(axis), Slice(start, end, step))
310+
&SliceOrIndex::Slice { start, end, step } => {
311+
self.slice_axis_inplace(Axis(axis), Slice { start, end, step })
312312
}
313313
&SliceOrIndex::Index(index) => {
314314
let i_usize = abs_index(self.len_of(Axis(axis)), index);
@@ -348,9 +348,9 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
348348
let offset = do_slice(
349349
&mut self.dim.slice_mut()[axis.index()],
350350
&mut self.strides.slice_mut()[axis.index()],
351-
indices.0,
352-
indices.1,
353-
indices.2,
351+
indices.start,
352+
indices.end,
353+
indices.step,
354354
);
355355
unsafe {
356356
self.ptr = self.ptr.offset(offset);

src/slice.rs

+98-39
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,88 @@ use super::{Dimension, Ixs};
1212

1313
/// A slice (range with step size).
1414
///
15+
/// Negative `begin` or `end` indexes are counted from the back of the axis. If
16+
/// `end` is `None`, the slice extends to the end of the axis.
17+
///
1518
/// ## Examples
1619
///
17-
/// `Slice(0, None, 1)` is the full range of an axis. It can also be created
18-
/// with `Slice::from(..)`. The Python equivalent is `[:]`.
20+
/// `Slice::new(0, None, 1)` is the full range of an axis. It can also be
21+
/// created with `Slice::from(..)`. The Python equivalent is `[:]`.
1922
///
20-
/// `Slice(a, Some(b), 2)` is every second element from `a` until `b`. It can
21-
/// also be created with `Slice::from(a..b).step(2)`. The Python equivalent is
22-
/// `[a:b:2]`.
23+
/// `Slice::new(a, b, 2)` is every second element from `a` until `b`. It can
24+
/// also be created with `Slice::from(a..b).step_by(2)`. The Python equivalent
25+
/// is `[a:b:2]`.
2326
///
24-
/// `Slice(a, None, -1)` is every element, from `a` until the end, in reverse
25-
/// order. It can also be created with `Slice::from(a..).step(-1)`. The Python
26-
/// equivalent is `[a::-1]`.
27+
/// `Slice::new(a, None, -1)` is every element, from `a` until the end, in
28+
/// reverse order. It can also be created with `Slice::from(a..).step_by(-1)`.
29+
/// The Python equivalent is `[a::-1]`.
2730
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
28-
pub struct Slice(pub Ixs, pub Option<Ixs>, pub Ixs);
31+
pub struct Slice {
32+
pub start: Ixs,
33+
pub end: Option<Ixs>,
34+
pub step: Ixs,
35+
}
2936

3037
impl Slice {
38+
pub fn new<I>(start: Ixs, end: I, step: Ixs) -> Slice
39+
where
40+
I: Into<Option<Ixs>>,
41+
{
42+
Slice {
43+
start,
44+
end: end.into(),
45+
step,
46+
}
47+
}
48+
3149
/// Returns a new `Slice` with the given step size.
3250
#[inline]
33-
pub fn step(self, step: Ixs) -> Self {
34-
Slice(self.0, self.1, step)
51+
pub fn step_by(self, step: Ixs) -> Self {
52+
Slice { step, ..self }
3553
}
3654
}
3755

3856
impl From<Range<Ixs>> for Slice {
3957
#[inline]
4058
fn from(r: Range<Ixs>) -> Slice {
41-
Slice(r.start, Some(r.end), 1)
59+
Slice {
60+
start: r.start,
61+
end: Some(r.end),
62+
step: 1,
63+
}
4264
}
4365
}
4466

4567
impl From<RangeFrom<Ixs>> for Slice {
4668
#[inline]
4769
fn from(r: RangeFrom<Ixs>) -> Slice {
48-
Slice(r.start, None, 1)
70+
Slice {
71+
start: r.start,
72+
end: None,
73+
step: 1,
74+
}
4975
}
5076
}
5177

5278
impl From<RangeTo<Ixs>> for Slice {
5379
#[inline]
5480
fn from(r: RangeTo<Ixs>) -> Slice {
55-
Slice(0, Some(r.end), 1)
81+
Slice {
82+
start: 0,
83+
end: Some(r.end),
84+
step: 1,
85+
}
5686
}
5787
}
5888

5989
impl From<RangeFull> for Slice {
6090
#[inline]
6191
fn from(_: RangeFull) -> Slice {
62-
Slice(0, None, 1)
92+
Slice {
93+
start: 0,
94+
end: None,
95+
step: 1,
96+
}
6397
}
6498
}
6599

@@ -74,24 +108,29 @@ impl From<RangeFull> for Slice {
74108
/// `SliceOrIndex::from(a)`. The Python equivalent is `[a]`. The macro
75109
/// equivalent is `s![a]`.
76110
///
77-
/// `SliceOrIndex::Slice(0, None, 1)` is the full range of an axis. It can also
78-
/// be created with `SliceOrIndex::from(..)`. The Python equivalent is `[:]`.
79-
/// The macro equivalent is `s![..]`.
111+
/// `SliceOrIndex::Slice { start: 0, end: None, step: 1}` is the full range of
112+
/// an axis. It can also be created with `SliceOrIndex::from(..)`. The Python
113+
/// equivalent is `[:]`. The macro equivalent is `s![..]`.
80114
///
81-
/// `SliceOrIndex::Slice(a, Some(b), 2)` is every second element from `a` until
82-
/// `b`. It can also be created with `SliceOrIndex::from(a..b).step(2)`. The
83-
/// Python equivalent is `[a:b:2]`. The macro equivalent is `s![a..b;2]`.
115+
/// `SliceOrIndex::Slice { start: a, end: Some(b), step: 2 }` is every second
116+
/// element from `a` until `b`. It can also be created with
117+
/// `SliceOrIndex::from(a..b).step_by(2)`. The Python equivalent is `[a:b:2]`.
118+
/// The macro equivalent is `s![a..b;2]`.
84119
///
85-
/// `SliceOrIndex::Slice(a, None, -1)` is every element, from `a` until the
86-
/// end, in reverse order. It can also be created with
87-
/// `SliceOrIndex::from(a..).step(-1)`. The Python equivalent is `[a::-1]`. The
88-
/// macro equivalent is `s![a..;-1]`.
120+
/// `SliceOrIndex::Slice { start: a, end: None, step: -1 }` is every element,
121+
/// from `a` until the end, in reverse order. It can also be created with
122+
/// `SliceOrIndex::from(a..).step_by(-1)`. The Python equivalent is `[a::-1]`.
123+
/// The macro equivalent is `s![a..;-1]`.
89124
#[derive(Debug, PartialEq, Eq, Hash)]
90125
pub enum SliceOrIndex {
91-
/// A range with step size. The fields are `begin`, `end`, and `step`,
92-
/// where negative `begin` or `end` indexes are counted from the back of
93-
/// the axis. If `end` is `None`, the slice extends to the end of the axis.
94-
Slice(Ixs, Option<Ixs>, Ixs),
126+
/// A range with step size. Negative `begin` or `end` indexes are counted
127+
/// from the back of the axis. If `end` is `None`, the slice extends to the
128+
/// end of the axis.
129+
Slice {
130+
start: Ixs,
131+
end: Option<Ixs>,
132+
step: Ixs,
133+
},
95134
/// A single index.
96135
Index(Ixs),
97136
}
@@ -102,7 +141,7 @@ impl SliceOrIndex {
102141
/// Returns `true` if `self` is a `Slice` value.
103142
pub fn is_slice(&self) -> bool {
104143
match self {
105-
&SliceOrIndex::Slice(..) => true,
144+
&SliceOrIndex::Slice { .. } => true,
106145
_ => false,
107146
}
108147
}
@@ -117,9 +156,9 @@ impl SliceOrIndex {
117156

118157
/// Returns a new `SliceOrIndex` with the given step size.
119158
#[inline]
120-
pub fn step(self, step: Ixs) -> Self {
159+
pub fn step_by(self, step: Ixs) -> Self {
121160
match self {
122-
SliceOrIndex::Slice(start, end, _) => SliceOrIndex::Slice(start, end, step),
161+
SliceOrIndex::Slice { start, end, .. } => SliceOrIndex::Slice { start, end, step },
123162
SliceOrIndex::Index(s) => SliceOrIndex::Index(s),
124163
}
125164
}
@@ -129,7 +168,7 @@ impl fmt::Display for SliceOrIndex {
129168
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130169
match *self {
131170
SliceOrIndex::Index(index) => write!(f, "{}", index)?,
132-
SliceOrIndex::Slice(start, end, step) => {
171+
SliceOrIndex::Slice { start, end, step } => {
133172
if start != 0 {
134173
write!(f, "{}", start)?;
135174
}
@@ -149,14 +188,22 @@ impl fmt::Display for SliceOrIndex {
149188
impl From<Slice> for SliceOrIndex {
150189
#[inline]
151190
fn from(s: Slice) -> SliceOrIndex {
152-
SliceOrIndex::Slice(s.0, s.1, s.2)
191+
SliceOrIndex::Slice {
192+
start: s.start,
193+
end: s.end,
194+
step: s.step,
195+
}
153196
}
154197
}
155198

156199
impl From<Range<Ixs>> for SliceOrIndex {
157200
#[inline]
158201
fn from(r: Range<Ixs>) -> SliceOrIndex {
159-
SliceOrIndex::Slice(r.start, Some(r.end), 1)
202+
SliceOrIndex::Slice {
203+
start: r.start,
204+
end: Some(r.end),
205+
step: 1,
206+
}
160207
}
161208
}
162209

@@ -170,21 +217,33 @@ impl From<Ixs> for SliceOrIndex {
170217
impl From<RangeFrom<Ixs>> for SliceOrIndex {
171218
#[inline]
172219
fn from(r: RangeFrom<Ixs>) -> SliceOrIndex {
173-
SliceOrIndex::Slice(r.start, None, 1)
220+
SliceOrIndex::Slice {
221+
start: r.start,
222+
end: None,
223+
step: 1,
224+
}
174225
}
175226
}
176227

177228
impl From<RangeTo<Ixs>> for SliceOrIndex {
178229
#[inline]
179230
fn from(r: RangeTo<Ixs>) -> SliceOrIndex {
180-
SliceOrIndex::Slice(0, Some(r.end), 1)
231+
SliceOrIndex::Slice {
232+
start: 0,
233+
end: Some(r.end),
234+
step: 1,
235+
}
181236
}
182237
}
183238

184239
impl From<RangeFull> for SliceOrIndex {
185240
#[inline]
186241
fn from(_: RangeFull) -> SliceOrIndex {
187-
SliceOrIndex::Slice(0, None, 1)
242+
SliceOrIndex::Slice {
243+
start: 0,
244+
end: None,
245+
step: 1,
246+
}
188247
}
189248
}
190249

@@ -483,7 +542,7 @@ macro_rules! s(
483542
};
484543
// convert range/index and step into SliceOrIndex
485544
(@convert $r:expr, $s:expr) => {
486-
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step($s)
545+
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s)
487546
};
488547
($($t:tt)*) => {
489548
s![@parse ::std::marker::PhantomData::<$crate::Ix0>, [] $($t)*]

tests/array.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn test_slice()
6060
*elt = i;
6161
}
6262

63-
let vi = A.slice(s![1.., ..;2, Slice(0, None, 2)]);
63+
let vi = A.slice(s![1.., ..;2, Slice::new(0, None, 2)]);
6464
assert_eq!(vi.shape(), &[2, 2, 3]);
6565
let vi = A.slice(s![.., .., ..]);
6666
assert_eq!(vi.shape(), A.shape());
@@ -119,7 +119,7 @@ fn test_slice_array_dyn() {
119119
let info = &SliceInfo::<_, IxDyn>::new([
120120
SliceOrIndex::from(1..),
121121
SliceOrIndex::from(1),
122-
SliceOrIndex::from(..).step(2),
122+
SliceOrIndex::from(..).step_by(2),
123123
]);
124124
arr.slice(info);
125125
arr.slice_mut(info);
@@ -133,7 +133,7 @@ fn test_slice_dyninput_array_dyn() {
133133
let info = &SliceInfo::<_, IxDyn>::new([
134134
SliceOrIndex::from(1..),
135135
SliceOrIndex::from(1),
136-
SliceOrIndex::from(..).step(2),
136+
SliceOrIndex::from(..).step_by(2),
137137
]);
138138
arr.slice(info);
139139
arr.slice_mut(info);
@@ -147,7 +147,7 @@ fn test_slice_dyninput_vec_fixed() {
147147
let info = &SliceInfo::<_, Ix2>::new(vec![
148148
SliceOrIndex::from(1..),
149149
SliceOrIndex::from(1),
150-
SliceOrIndex::from(..).step(2),
150+
SliceOrIndex::from(..).step_by(2),
151151
]);
152152
arr.slice(info.as_ref());
153153
arr.slice_mut(info.as_ref());
@@ -161,7 +161,7 @@ fn test_slice_dyninput_vec_dyn() {
161161
let info = &SliceInfo::<_, IxDyn>::new(vec![
162162
SliceOrIndex::from(1..),
163163
SliceOrIndex::from(1),
164-
SliceOrIndex::from(..).step(2),
164+
SliceOrIndex::from(..).step_by(2),
165165
]);
166166
arr.slice(info.as_ref());
167167
arr.slice_mut(info.as_ref());
@@ -252,7 +252,7 @@ fn slice_oob()
252252
#[test]
253253
fn slice_axis_oob() {
254254
let a = RcArray::<i32, _>::zeros((3, 4));
255-
let _vi = a.slice_axis(Axis(0), Slice(0, Some(10), 1));
255+
let _vi = a.slice_axis(Axis(0), Slice::new(0, 10, 1));
256256
}
257257

258258
#[should_panic]

tests/oper.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,11 @@ fn scaled_add_3() {
577577
vec![n, q]
578578
};
579579
let cslice = if n == 1 {
580-
vec![SliceOrIndex::from(..).step(s2)]
580+
vec![SliceOrIndex::from(..).step_by(s2)]
581581
} else {
582582
vec![
583-
SliceOrIndex::from(..).step(s1),
584-
SliceOrIndex::from(..).step(s2),
583+
SliceOrIndex::from(..).step_by(s1),
584+
SliceOrIndex::from(..).step_by(s2),
585585
]
586586
};
587587

0 commit comments

Comments
 (0)