From 3acf46496b6bff5dfb4122de23e75cd038374ac7 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Mon, 30 Oct 2017 14:26:26 -0400 Subject: [PATCH] Add support for more index types in s![] macro This commit also removes use of the `Ixs` type alias in the `slice` module. --- src/slice.rs | 196 +++++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 86 deletions(-) diff --git a/src/slice.rs b/src/slice.rs index c3e8585a8..1e57cae1f 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -8,7 +8,7 @@ use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeTo}; use std::fmt; use std::marker::PhantomData; -use super::{Dimension, Ixs}; +use super::Dimension; /// A slice (range with step size). /// @@ -63,39 +63,47 @@ impl Slice { } } -impl From> for Slice { - #[inline] - fn from(r: Range) -> Slice { - Slice { - start: r.start, - end: Some(r.end), - step: 1, +macro_rules! impl_slice_from_index_type { + ($index:ty) => { + impl From> for Slice { + #[inline] + fn from(r: Range<$index>) -> Slice { + Slice { + start: r.start as isize, + end: Some(r.end as isize), + step: 1, + } + } } - } -} -impl From> for Slice { - #[inline] - fn from(r: RangeFrom) -> Slice { - Slice { - start: r.start, - end: None, - step: 1, + impl From> for Slice { + #[inline] + fn from(r: RangeFrom<$index>) -> Slice { + Slice { + start: r.start as isize, + end: None, + step: 1, + } + } } - } -} -impl From> for Slice { - #[inline] - fn from(r: RangeTo) -> Slice { - Slice { - start: 0, - end: Some(r.end), - step: 1, + impl From> for Slice { + #[inline] + fn from(r: RangeTo<$index>) -> Slice { + Slice { + start: 0, + end: Some(r.end as isize), + step: 1, + } + } } } } +impl_slice_from_index_type!(isize); +impl_slice_from_index_type!(usize); +impl_slice_from_index_type!(i32); + impl From for Slice { #[inline] fn from(_: RangeFull) -> Slice { @@ -137,12 +145,12 @@ pub enum SliceOrIndex { /// from the back of the axis. If `end` is `None`, the slice extends to the /// end of the axis. Slice { - start: Ixs, - end: Option, - step: Ixs, + start: isize, + end: Option, + step: isize, }, /// A single index. - Index(Ixs), + Index(isize), } copy_and_clone!{SliceOrIndex} @@ -166,7 +174,7 @@ impl SliceOrIndex { /// Returns a new `SliceOrIndex` with the given step size. #[inline] - pub fn step_by(self, step: Ixs) -> Self { + pub fn step_by(self, step: isize) -> Self { match self { SliceOrIndex::Slice { start, end, .. } => SliceOrIndex::Slice { start, end, step }, SliceOrIndex::Index(s) => SliceOrIndex::Index(s), @@ -206,46 +214,54 @@ impl From for SliceOrIndex { } } -impl From> for SliceOrIndex { - #[inline] - fn from(r: Range) -> SliceOrIndex { - SliceOrIndex::Slice { - start: r.start, - end: Some(r.end), - step: 1, +macro_rules! impl_sliceorindex_from_index_type { + ($index:ty) => { + impl From<$index> for SliceOrIndex { + #[inline] + fn from(r: $index) -> SliceOrIndex { + SliceOrIndex::Index(r as isize) + } } - } -} -impl From for SliceOrIndex { - #[inline] - fn from(r: Ixs) -> SliceOrIndex { - SliceOrIndex::Index(r) - } -} + impl From> for SliceOrIndex { + #[inline] + fn from(r: Range<$index>) -> SliceOrIndex { + SliceOrIndex::Slice { + start: r.start as isize, + end: Some(r.end as isize), + step: 1, + } + } + } -impl From> for SliceOrIndex { - #[inline] - fn from(r: RangeFrom) -> SliceOrIndex { - SliceOrIndex::Slice { - start: r.start, - end: None, - step: 1, + impl From> for SliceOrIndex { + #[inline] + fn from(r: RangeFrom<$index>) -> SliceOrIndex { + SliceOrIndex::Slice { + start: r.start as isize, + end: None, + step: 1, + } + } } - } -} -impl From> for SliceOrIndex { - #[inline] - fn from(r: RangeTo) -> SliceOrIndex { - SliceOrIndex::Slice { - start: 0, - end: Some(r.end), - step: 1, + impl From> for SliceOrIndex { + #[inline] + fn from(r: RangeTo<$index>) -> SliceOrIndex { + SliceOrIndex::Slice { + start: 0, + end: Some(r.end as isize), + step: 1, + } + } } } } +impl_sliceorindex_from_index_type!(isize); +impl_sliceorindex_from_index_type!(usize); +impl_sliceorindex_from_index_type!(i32); + impl From for SliceOrIndex { #[inline] fn from(_: RangeFull) -> SliceOrIndex { @@ -400,36 +416,44 @@ impl SliceNextDim for Slice { } } -impl SliceNextDim for Range { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } -} +macro_rules! impl_slicenextdim_for_index_type { + ($index:ty) => { + impl SliceNextDim for $index { + fn next_dim(&self, _: PhantomData) -> PhantomData { + PhantomData + } + } -impl SliceNextDim for RangeFrom { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } -} + impl SliceNextDim for Range<$index> { + fn next_dim(&self, _: PhantomData) -> PhantomData { + PhantomData + } + } -impl SliceNextDim for RangeTo { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData + impl SliceNextDim for RangeFrom<$index> { + fn next_dim(&self, _: PhantomData) -> PhantomData { + PhantomData + } + } + + impl SliceNextDim for RangeTo<$index> { + fn next_dim(&self, _: PhantomData) -> PhantomData { + PhantomData + } + } } } +impl_slicenextdim_for_index_type!(isize); +impl_slicenextdim_for_index_type!(usize); +impl_slicenextdim_for_index_type!(i32); + impl SliceNextDim for RangeFull { fn next_dim(&self, _: PhantomData) -> PhantomData { PhantomData } } -impl SliceNextDim for Ixs { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } -} - /// Slice argument constructor. /// /// `s![]` takes a list of ranges/slices/indices, separated by comma, with @@ -456,10 +480,10 @@ impl SliceNextDim for Ixs { /// /// The number of *axis-slice-or-index* must match the number of axes in the /// array. *index*, *range*, *slice*, and *step* can be expressions. *index* -/// and *step* must be of type [`Ixs`]. *range* can be of type `Range`, -/// `RangeTo`, `RangeFrom`, or `RangeFull`. -/// -/// [`Ixs`]: type.Ixs.html +/// must be of type `isize`, `usize`, or `i32`. *range* must be of type +/// `Range`, `RangeTo`, `RangeFrom`, or `RangeFull` where `I` is +/// `isize`, `usize`, or `i32`. *step* must be a type that can be converted to +/// `isize` with the `as` keyword. /// /// For example `s![0..4;2, 6, 1..5]` is a slice of the first axis for 0..4 /// with step size 2, a subview of the second axis at index 6, and a slice of @@ -552,7 +576,7 @@ macro_rules! s( }; // convert range/index and step into SliceOrIndex (@convert $r:expr, $s:expr) => { - <$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s) + <$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s as isize) }; ($($t:tt)*) => { s![@parse ::std::marker::PhantomData::<$crate::Ix0>, [] $($t)*]