Skip to content

Commit 3acf464

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 9ac07d7 commit 3acf464

File tree

1 file changed

+110
-86
lines changed

1 file changed

+110
-86
lines changed

src/slice.rs

+110-86
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
///
@@ -63,39 +63,47 @@ impl Slice {
6363
}
6464
}
6565

66-
impl From<Range<Ixs>> for Slice {
67-
#[inline]
68-
fn from(r: Range<Ixs>) -> Slice {
69-
Slice {
70-
start: r.start,
71-
end: Some(r.end),
72-
step: 1,
66+
macro_rules! impl_slice_from_index_type {
67+
($index:ty) => {
68+
impl From<Range<$index>> for Slice {
69+
#[inline]
70+
fn from(r: Range<$index>) -> Slice {
71+
Slice {
72+
start: r.start as isize,
73+
end: Some(r.end as isize),
74+
step: 1,
75+
}
76+
}
7377
}
74-
}
75-
}
7678

77-
impl From<RangeFrom<Ixs>> for Slice {
78-
#[inline]
79-
fn from(r: RangeFrom<Ixs>) -> Slice {
80-
Slice {
81-
start: r.start,
82-
end: None,
83-
step: 1,
79+
impl From<RangeFrom<$index>> for Slice {
80+
#[inline]
81+
fn from(r: RangeFrom<$index>) -> Slice {
82+
Slice {
83+
start: r.start as isize,
84+
end: None,
85+
step: 1,
86+
}
87+
}
8488
}
85-
}
86-
}
8789

88-
impl From<RangeTo<Ixs>> for Slice {
89-
#[inline]
90-
fn from(r: RangeTo<Ixs>) -> Slice {
91-
Slice {
92-
start: 0,
93-
end: Some(r.end),
94-
step: 1,
90+
impl From<RangeTo<$index>> for Slice {
91+
#[inline]
92+
fn from(r: RangeTo<$index>) -> Slice {
93+
Slice {
94+
start: 0,
95+
end: Some(r.end as isize),
96+
step: 1,
97+
}
98+
}
9599
}
96100
}
97101
}
98102

103+
impl_slice_from_index_type!(isize);
104+
impl_slice_from_index_type!(usize);
105+
impl_slice_from_index_type!(i32);
106+
99107
impl From<RangeFull> for Slice {
100108
#[inline]
101109
fn from(_: RangeFull) -> Slice {
@@ -137,12 +145,12 @@ pub enum SliceOrIndex {
137145
/// from the back of the axis. If `end` is `None`, the slice extends to the
138146
/// end of the axis.
139147
Slice {
140-
start: Ixs,
141-
end: Option<Ixs>,
142-
step: Ixs,
148+
start: isize,
149+
end: Option<isize>,
150+
step: isize,
143151
},
144152
/// A single index.
145-
Index(Ixs),
153+
Index(isize),
146154
}
147155

148156
copy_and_clone!{SliceOrIndex}
@@ -166,7 +174,7 @@ impl SliceOrIndex {
166174

167175
/// Returns a new `SliceOrIndex` with the given step size.
168176
#[inline]
169-
pub fn step_by(self, step: Ixs) -> Self {
177+
pub fn step_by(self, step: isize) -> Self {
170178
match self {
171179
SliceOrIndex::Slice { start, end, .. } => SliceOrIndex::Slice { start, end, step },
172180
SliceOrIndex::Index(s) => SliceOrIndex::Index(s),
@@ -206,46 +214,54 @@ impl From<Slice> for SliceOrIndex {
206214
}
207215
}
208216

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

220-
impl From<Ixs> for SliceOrIndex {
221-
#[inline]
222-
fn from(r: Ixs) -> SliceOrIndex {
223-
SliceOrIndex::Index(r)
224-
}
225-
}
226+
impl From<Range<$index>> for SliceOrIndex {
227+
#[inline]
228+
fn from(r: Range<$index>) -> SliceOrIndex {
229+
SliceOrIndex::Slice {
230+
start: r.start as isize,
231+
end: Some(r.end as isize),
232+
step: 1,
233+
}
234+
}
235+
}
226236

227-
impl From<RangeFrom<Ixs>> for SliceOrIndex {
228-
#[inline]
229-
fn from(r: RangeFrom<Ixs>) -> SliceOrIndex {
230-
SliceOrIndex::Slice {
231-
start: r.start,
232-
end: None,
233-
step: 1,
237+
impl From<RangeFrom<$index>> for SliceOrIndex {
238+
#[inline]
239+
fn from(r: RangeFrom<$index>) -> SliceOrIndex {
240+
SliceOrIndex::Slice {
241+
start: r.start as isize,
242+
end: None,
243+
step: 1,
244+
}
245+
}
234246
}
235-
}
236-
}
237247

238-
impl From<RangeTo<Ixs>> for SliceOrIndex {
239-
#[inline]
240-
fn from(r: RangeTo<Ixs>) -> SliceOrIndex {
241-
SliceOrIndex::Slice {
242-
start: 0,
243-
end: Some(r.end),
244-
step: 1,
248+
impl From<RangeTo<$index>> for SliceOrIndex {
249+
#[inline]
250+
fn from(r: RangeTo<$index>) -> SliceOrIndex {
251+
SliceOrIndex::Slice {
252+
start: 0,
253+
end: Some(r.end as isize),
254+
step: 1,
255+
}
256+
}
245257
}
246258
}
247259
}
248260

261+
impl_sliceorindex_from_index_type!(isize);
262+
impl_sliceorindex_from_index_type!(usize);
263+
impl_sliceorindex_from_index_type!(i32);
264+
249265
impl From<RangeFull> for SliceOrIndex {
250266
#[inline]
251267
fn from(_: RangeFull) -> SliceOrIndex {
@@ -400,36 +416,44 @@ impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Slice {
400416
}
401417
}
402418

403-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Range<Ixs> {
404-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
405-
PhantomData
406-
}
407-
}
419+
macro_rules! impl_slicenextdim_for_index_type {
420+
($index:ty) => {
421+
impl<D1: Dimension> SliceNextDim<D1, D1> for $index {
422+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1> {
423+
PhantomData
424+
}
425+
}
408426

409-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFrom<Ixs> {
410-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
411-
PhantomData
412-
}
413-
}
427+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for Range<$index> {
428+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
429+
PhantomData
430+
}
431+
}
414432

415-
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeTo<Ixs> {
416-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
417-
PhantomData
433+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFrom<$index> {
434+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
435+
PhantomData
436+
}
437+
}
438+
439+
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeTo<$index> {
440+
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
441+
PhantomData
442+
}
443+
}
418444
}
419445
}
420446

447+
impl_slicenextdim_for_index_type!(isize);
448+
impl_slicenextdim_for_index_type!(usize);
449+
impl_slicenextdim_for_index_type!(i32);
450+
421451
impl<D1: Dimension> SliceNextDim<D1, D1::Larger> for RangeFull {
422452
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1::Larger> {
423453
PhantomData
424454
}
425455
}
426456

427-
impl<D1: Dimension> SliceNextDim<D1, D1> for Ixs {
428-
fn next_dim(&self, _: PhantomData<D1>) -> PhantomData<D1> {
429-
PhantomData
430-
}
431-
}
432-
433457
/// Slice argument constructor.
434458
///
435459
/// `s![]` takes a list of ranges/slices/indices, separated by comma, with
@@ -456,10 +480,10 @@ impl<D1: Dimension> SliceNextDim<D1, D1> for Ixs {
456480
///
457481
/// The number of *axis-slice-or-index* must match the number of axes in the
458482
/// array. *index*, *range*, *slice*, and *step* can be expressions. *index*
459-
/// and *step* must be of type [`Ixs`]. *range* can be of type `Range<Ixs>`,
460-
/// `RangeTo<Ixs>`, `RangeFrom<Ixs>`, or `RangeFull`.
461-
///
462-
/// [`Ixs`]: type.Ixs.html
483+
/// must be of type `isize`, `usize`, or `i32`. *range* must be of type
484+
/// `Range<I>`, `RangeTo<I>`, `RangeFrom<I>`, or `RangeFull` where `I` is
485+
/// `isize`, `usize`, or `i32`. *step* must be a type that can be converted to
486+
/// `isize` with the `as` keyword.
463487
///
464488
/// For example `s![0..4;2, 6, 1..5]` is a slice of the first axis for 0..4
465489
/// with step size 2, a subview of the second axis at index 6, and a slice of
@@ -552,7 +576,7 @@ macro_rules! s(
552576
};
553577
// convert range/index and step into SliceOrIndex
554578
(@convert $r:expr, $s:expr) => {
555-
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s)
579+
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s as isize)
556580
};
557581
($($t:tt)*) => {
558582
s![@parse ::std::marker::PhantomData::<$crate::Ix0>, [] $($t)*]

0 commit comments

Comments
 (0)