Skip to content

Commit 240515e

Browse files
committed
Add support for more index types in s![] macro
This commit also removes use of the `Ixs` type alias in the `slice` module.
1 parent 5802f00 commit 240515e

File tree

1 file changed

+116
-92
lines changed

1 file changed

+116
-92
lines changed

src/slice.rs

Lines changed: 116 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeTo};
99
use std::fmt;
1010
use std::marker::PhantomData;
11-
use super::{Dimension, Ixs};
11+
use super::Dimension;
1212

1313
/// A slice (range with step size).
1414
///
@@ -29,15 +29,15 @@ use super::{Dimension, Ixs};
2929
/// The Python equivalent is `[a::-1]`.
3030
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
3131
pub struct Slice {
32-
pub start: Ixs,
33-
pub end: Option<Ixs>,
34-
pub step: Ixs,
32+
pub start: isize,
33+
pub end: Option<isize>,
34+
pub step: isize,
3535
}
3636

3737
impl Slice {
38-
pub fn new<I>(start: Ixs, end: I, step: Ixs) -> Slice
38+
pub fn new<I>(start: isize, end: I, step: isize) -> Slice
3939
where
40-
I: Into<Option<Ixs>>,
40+
I: Into<Option<isize>>,
4141
{
4242
Slice {
4343
start,
@@ -48,44 +48,52 @@ impl Slice {
4848

4949
/// Returns a new `Slice` with the given step size.
5050
#[inline]
51-
pub fn step_by(self, step: Ixs) -> Self {
51+
pub fn step_by(self, step: isize) -> Self {
5252
Slice { step, ..self }
5353
}
5454
}
5555

56-
impl From<Range<Ixs>> for Slice {
57-
#[inline]
58-
fn from(r: Range<Ixs>) -> Slice {
59-
Slice {
60-
start: r.start,
61-
end: Some(r.end),
62-
step: 1,
56+
macro_rules! impl_slice_from_index_type {
57+
($index:ty) => {
58+
impl From<Range<$index>> for Slice {
59+
#[inline]
60+
fn from(r: Range<$index>) -> Slice {
61+
Slice {
62+
start: r.start as isize,
63+
end: Some(r.end as isize),
64+
step: 1,
65+
}
66+
}
6367
}
64-
}
65-
}
6668

67-
impl From<RangeFrom<Ixs>> for Slice {
68-
#[inline]
69-
fn from(r: RangeFrom<Ixs>) -> Slice {
70-
Slice {
71-
start: r.start,
72-
end: None,
73-
step: 1,
69+
impl From<RangeFrom<$index>> for Slice {
70+
#[inline]
71+
fn from(r: RangeFrom<$index>) -> Slice {
72+
Slice {
73+
start: r.start as isize,
74+
end: None,
75+
step: 1,
76+
}
77+
}
7478
}
75-
}
76-
}
7779

78-
impl From<RangeTo<Ixs>> for Slice {
79-
#[inline]
80-
fn from(r: RangeTo<Ixs>) -> Slice {
81-
Slice {
82-
start: 0,
83-
end: Some(r.end),
84-
step: 1,
80+
impl From<RangeTo<$index>> for Slice {
81+
#[inline]
82+
fn from(r: RangeTo<$index>) -> Slice {
83+
Slice {
84+
start: 0,
85+
end: Some(r.end as isize),
86+
step: 1,
87+
}
88+
}
8589
}
8690
}
8791
}
8892

93+
impl_slice_from_index_type!(isize);
94+
impl_slice_from_index_type!(usize);
95+
impl_slice_from_index_type!(i32);
96+
8997
impl From<RangeFull> for Slice {
9098
#[inline]
9199
fn from(_: RangeFull) -> Slice {
@@ -127,12 +135,12 @@ pub enum SliceOrIndex {
127135
/// from the back of the axis. If `end` is `None`, the slice extends to the
128136
/// end of the axis.
129137
Slice {
130-
start: Ixs,
131-
end: Option<Ixs>,
132-
step: Ixs,
138+
start: isize,
139+
end: Option<isize>,
140+
step: isize,
133141
},
134142
/// A single index.
135-
Index(Ixs),
143+
Index(isize),
136144
}
137145

138146
copy_and_clone!{SliceOrIndex}
@@ -156,7 +164,7 @@ impl SliceOrIndex {
156164

157165
/// Returns a new `SliceOrIndex` with the given step size.
158166
#[inline]
159-
pub fn step_by(self, step: Ixs) -> Self {
167+
pub fn step_by(self, step: isize) -> Self {
160168
match self {
161169
SliceOrIndex::Slice { start, end, .. } => SliceOrIndex::Slice { start, end, step },
162170
SliceOrIndex::Index(s) => SliceOrIndex::Index(s),
@@ -196,46 +204,54 @@ impl From<Slice> for SliceOrIndex {
196204
}
197205
}
198206

199-
impl From<Range<Ixs>> for SliceOrIndex {
200-
#[inline]
201-
fn from(r: Range<Ixs>) -> SliceOrIndex {
202-
SliceOrIndex::Slice {
203-
start: r.start,
204-
end: Some(r.end),
205-
step: 1,
207+
macro_rules! impl_sliceorindex_from_index_type {
208+
($index:ty) => {
209+
impl From<$index> for SliceOrIndex {
210+
#[inline]
211+
fn from(r: $index) -> SliceOrIndex {
212+
SliceOrIndex::Index(r as isize)
213+
}
206214
}
207-
}
208-
}
209215

210-
impl From<Ixs> for SliceOrIndex {
211-
#[inline]
212-
fn from(r: Ixs) -> SliceOrIndex {
213-
SliceOrIndex::Index(r)
214-
}
215-
}
216+
impl From<Range<$index>> for SliceOrIndex {
217+
#[inline]
218+
fn from(r: Range<$index>) -> SliceOrIndex {
219+
SliceOrIndex::Slice {
220+
start: r.start as isize,
221+
end: Some(r.end as isize),
222+
step: 1,
223+
}
224+
}
225+
}
216226

217-
impl From<RangeFrom<Ixs>> for SliceOrIndex {
218-
#[inline]
219-
fn from(r: RangeFrom<Ixs>) -> SliceOrIndex {
220-
SliceOrIndex::Slice {
221-
start: r.start,
222-
end: None,
223-
step: 1,
227+
impl From<RangeFrom<$index>> for SliceOrIndex {
228+
#[inline]
229+
fn from(r: RangeFrom<$index>) -> SliceOrIndex {
230+
SliceOrIndex::Slice {
231+
start: r.start as isize,
232+
end: None,
233+
step: 1,
234+
}
235+
}
224236
}
225-
}
226-
}
227237

228-
impl From<RangeTo<Ixs>> for SliceOrIndex {
229-
#[inline]
230-
fn from(r: RangeTo<Ixs>) -> SliceOrIndex {
231-
SliceOrIndex::Slice {
232-
start: 0,
233-
end: Some(r.end),
234-
step: 1,
238+
impl From<RangeTo<$index>> for SliceOrIndex {
239+
#[inline]
240+
fn from(r: RangeTo<$index>) -> SliceOrIndex {
241+
SliceOrIndex::Slice {
242+
start: 0,
243+
end: Some(r.end as isize),
244+
step: 1,
245+
}
246+
}
235247
}
236248
}
237249
}
238250

251+
impl_sliceorindex_from_index_type!(isize);
252+
impl_sliceorindex_from_index_type!(usize);
253+
impl_sliceorindex_from_index_type!(i32);
254+
239255
impl From<RangeFull> for SliceOrIndex {
240256
#[inline]
241257
fn from(_: RangeFull) -> SliceOrIndex {
@@ -390,36 +406,44 @@ impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Slice {
390406
}
391407
}
392408

393-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Range<Ixs> {
394-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
395-
PhantomData
396-
}
397-
}
409+
macro_rules! impl_slicenextdim_for_index_type {
410+
($index:ty) => {
411+
impl<D1: Dimension> SliceNextDim<D1, D1> for $index {
412+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1> {
413+
PhantomData
414+
}
415+
}
398416

399-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFrom<Ixs> {
400-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
401-
PhantomData
402-
}
403-
}
417+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Range<$index> {
418+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
419+
PhantomData
420+
}
421+
}
404422

405-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeTo<Ixs> {
406-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
407-
PhantomData
423+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFrom<$index> {
424+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
425+
PhantomData
426+
}
427+
}
428+
429+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeTo<$index> {
430+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
431+
PhantomData
432+
}
433+
}
408434
}
409435
}
410436

437+
impl_slicenextdim_for_index_type!(isize);
438+
impl_slicenextdim_for_index_type!(usize);
439+
impl_slicenextdim_for_index_type!(i32);
440+
411441
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFull {
412442
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
413443
PhantomData
414444
}
415445
}
416446

417-
impl<D1: Dimension> SliceNextDim<D1, D1> for Ixs {
418-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1> {
419-
PhantomData
420-
}
421-
}
422-
423447
/// Slice argument constructor.
424448
///
425449
/// `s![]` takes a list of ranges/slices/indices, separated by comma, with
@@ -446,10 +470,10 @@ impl<D1: Dimension> SliceNextDim<D1, D1> for Ixs {
446470
///
447471
/// The number of *axis-slice-or-index* must match the number of axes in the
448472
/// array. *index*, *range*, *slice*, and *step* can be expressions. *index*
449-
/// and *step* must be of type [`Ixs`]. *range* can be of type `Range<Ixs>`,
450-
/// `RangeTo<Ixs>`, `RangeFrom<Ixs>`, or `RangeFull`.
451-
///
452-
/// [`Ixs`]: type.Ixs.html
473+
/// must be of type `isize`, `usize`, or `i32`. *range* must be of type
474+
/// `Range<I>`, `RangeTo<I>`, `RangeFrom<I>`, or `RangeFull` where `I` is
475+
/// `isize`, `usize`, or `i32`. *step* must be a type that can be converted to
476+
/// `isize` with the `as` keyword.
453477
///
454478
/// For example `s![0..4;2, 6, 1..5]` is a slice of the first axis for 0..4
455479
/// with step size 2, a subview of the second axis at index 6, and a slice of
@@ -542,7 +566,7 @@ macro_rules! s(
542566
};
543567
// convert range/index and step into SliceOrIndex
544568
(@convert $r:expr, $s:expr) => {
545-
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s)
569+
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s as isize)
546570
};
547571
($($t:tt)*) => {
548572
s![@parse ::std::marker::PhantomData::<$crate::Ix0>, [] $($t)*]

0 commit comments

Comments
 (0)