66// option. This file may not be copied, modified, or distributed
77// except according to those terms.
88use error:: { ShapeError , ErrorKind } ;
9- use std:: ops:: { Deref , Range , RangeFrom , RangeFull , RangeTo } ;
9+ use std:: ops:: { Deref , Range , RangeFrom , RangeFull , RangeInclusive , RangeTo , RangeToInclusive } ;
1010use std:: fmt;
1111use std:: marker:: PhantomData ;
1212use super :: Dimension ;
1313
1414/// A slice (range with step size).
1515///
16- /// Negative `begin` or `end` indexes are counted from the back of the axis. If
17- /// `end` is `None`, the slice extends to the end of the axis.
16+ /// `end` is an exclusive index. Negative `begin` or `end` indexes are counted
17+ /// from the back of the axis. If `end` is `None`, the slice extends to the end
18+ /// of the axis.
1819///
1920/// See also the [`s![]`](macro.s.html) macro.
2021///
@@ -66,58 +67,6 @@ impl Slice {
6667 }
6768}
6869
69- macro_rules! impl_slice_from_index_type {
70- ( $index: ty) => {
71- impl From <Range <$index>> for Slice {
72- #[ inline]
73- fn from( r: Range <$index>) -> Slice {
74- Slice {
75- start: r. start as isize ,
76- end: Some ( r. end as isize ) ,
77- step: 1 ,
78- }
79- }
80- }
81-
82- impl From <RangeFrom <$index>> for Slice {
83- #[ inline]
84- fn from( r: RangeFrom <$index>) -> Slice {
85- Slice {
86- start: r. start as isize ,
87- end: None ,
88- step: 1 ,
89- }
90- }
91- }
92-
93- impl From <RangeTo <$index>> for Slice {
94- #[ inline]
95- fn from( r: RangeTo <$index>) -> Slice {
96- Slice {
97- start: 0 ,
98- end: Some ( r. end as isize ) ,
99- step: 1 ,
100- }
101- }
102- }
103- }
104- }
105-
106- impl_slice_from_index_type ! ( isize ) ;
107- impl_slice_from_index_type ! ( usize ) ;
108- impl_slice_from_index_type ! ( i32 ) ;
109-
110- impl From < RangeFull > for Slice {
111- #[ inline]
112- fn from ( _: RangeFull ) -> Slice {
113- Slice {
114- start : 0 ,
115- end : None ,
116- step : 1 ,
117- }
118- }
119- }
120-
12170/// A slice (range with step) or an index.
12271///
12372/// See also the [`s![]`](macro.s!.html) macro for a convenient way to create a
@@ -144,9 +93,9 @@ impl From<RangeFull> for Slice {
14493/// The macro equivalent is `s![a..;-1]`.
14594#[ derive( Debug , PartialEq , Eq , Hash ) ]
14695pub enum SliceOrIndex {
147- /// A range with step size. Negative `begin` or `end` indexes are counted
148- /// from the back of the axis. If `end` is `None`, the slice extends to the
149- /// end of the axis.
96+ /// A range with step size. `end` is an exclusive index. Negative `begin`
97+ /// or `end` indexes are counted from the back of the axis. If `end` is
98+ /// `None`, the slice extends to the end of the axis.
15099 Slice {
151100 start : isize ,
152101 end : Option < isize > ,
@@ -219,64 +168,83 @@ impl fmt::Display for SliceOrIndex {
219168 }
220169}
221170
222- impl From < Slice > for SliceOrIndex {
223- #[ inline]
224- fn from ( s : Slice ) -> SliceOrIndex {
225- SliceOrIndex :: Slice {
226- start : s. start ,
227- end : s. end ,
228- step : s. step ,
229- }
230- }
231- }
232-
233- macro_rules! impl_sliceorindex_from_index_type {
234- ( $index: ty) => {
235- impl From <$index> for SliceOrIndex {
171+ macro_rules! impl_slice_variant_from_range {
172+ ( $self: ty, $constructor: path, $index: ty) => {
173+ impl From <Range <$index>> for $self {
236174 #[ inline]
237- fn from( r: $index) -> SliceOrIndex {
238- SliceOrIndex :: Index ( r as isize )
175+ fn from( r: Range <$index>) -> $self {
176+ $constructor {
177+ start: r. start as isize ,
178+ end: Some ( r. end as isize ) ,
179+ step: 1 ,
180+ }
239181 }
240182 }
241183
242- impl From <Range <$index>> for SliceOrIndex {
184+ impl From <RangeInclusive <$index>> for $self {
243185 #[ inline]
244- fn from( r: Range <$index>) -> SliceOrIndex {
245- SliceOrIndex :: Slice {
246- start: r. start as isize ,
247- end: Some ( r. end as isize ) ,
186+ fn from( r: RangeInclusive <$index>) -> $self {
187+ let end = * r. end( ) as isize ;
188+ $constructor {
189+ start: * r. start( ) as isize ,
190+ end: if end == -1 { None } else { Some ( end + 1 ) } ,
248191 step: 1 ,
249192 }
250193 }
251194 }
252195
253- impl From <RangeFrom <$index>> for SliceOrIndex {
196+ impl From <RangeFrom <$index>> for $self {
254197 #[ inline]
255- fn from( r: RangeFrom <$index>) -> SliceOrIndex {
256- SliceOrIndex :: Slice {
198+ fn from( r: RangeFrom <$index>) -> $self {
199+ $constructor {
257200 start: r. start as isize ,
258201 end: None ,
259202 step: 1 ,
260203 }
261204 }
262205 }
263206
264- impl From <RangeTo <$index>> for SliceOrIndex {
207+ impl From <RangeTo <$index>> for $self {
265208 #[ inline]
266- fn from( r: RangeTo <$index>) -> SliceOrIndex {
267- SliceOrIndex :: Slice {
209+ fn from( r: RangeTo <$index>) -> $self {
210+ $constructor {
268211 start: 0 ,
269212 end: Some ( r. end as isize ) ,
270213 step: 1 ,
271214 }
272215 }
273216 }
274- }
217+
218+ impl From <RangeToInclusive <$index>> for $self {
219+ #[ inline]
220+ fn from( r: RangeToInclusive <$index>) -> $self {
221+ let end = r. end as isize ;
222+ $constructor {
223+ start: 0 ,
224+ end: if end == -1 { None } else { Some ( end + 1 ) } ,
225+ step: 1 ,
226+ }
227+ }
228+ }
229+ } ;
275230}
231+ impl_slice_variant_from_range ! ( Slice , Slice , isize ) ;
232+ impl_slice_variant_from_range ! ( Slice , Slice , usize ) ;
233+ impl_slice_variant_from_range ! ( Slice , Slice , i32 ) ;
234+ impl_slice_variant_from_range ! ( SliceOrIndex , SliceOrIndex :: Slice , isize ) ;
235+ impl_slice_variant_from_range ! ( SliceOrIndex , SliceOrIndex :: Slice , usize ) ;
236+ impl_slice_variant_from_range ! ( SliceOrIndex , SliceOrIndex :: Slice , i32 ) ;
276237
277- impl_sliceorindex_from_index_type ! ( isize ) ;
278- impl_sliceorindex_from_index_type ! ( usize ) ;
279- impl_sliceorindex_from_index_type ! ( i32 ) ;
238+ impl From < RangeFull > for Slice {
239+ #[ inline]
240+ fn from ( _: RangeFull ) -> Slice {
241+ Slice {
242+ start : 0 ,
243+ end : None ,
244+ step : 1 ,
245+ }
246+ }
247+ }
280248
281249impl From < RangeFull > for SliceOrIndex {
282250 #[ inline]
@@ -289,6 +257,31 @@ impl From<RangeFull> for SliceOrIndex {
289257 }
290258}
291259
260+ impl From < Slice > for SliceOrIndex {
261+ #[ inline]
262+ fn from ( s : Slice ) -> SliceOrIndex {
263+ SliceOrIndex :: Slice {
264+ start : s. start ,
265+ end : s. end ,
266+ step : s. step ,
267+ }
268+ }
269+ }
270+
271+ macro_rules! impl_sliceorindex_from_index {
272+ ( $index: ty) => {
273+ impl From <$index> for SliceOrIndex {
274+ #[ inline]
275+ fn from( r: $index) -> SliceOrIndex {
276+ SliceOrIndex :: Index ( r as isize )
277+ }
278+ }
279+ } ;
280+ }
281+ impl_sliceorindex_from_index ! ( isize ) ;
282+ impl_sliceorindex_from_index ! ( usize ) ;
283+ impl_sliceorindex_from_index ! ( i32 ) ;
284+
292285/// Represents all of the necessary information to perform a slice.
293286///
294287/// The type `T` is typically `[SliceOrIndex; n]`, `[SliceOrIndex]`, or
@@ -427,49 +420,35 @@ pub trait SliceNextDim<D1, D2> {
427420 fn next_dim ( & self , PhantomData < D1 > ) -> PhantomData < D2 > ;
428421}
429422
430- impl < D1 : Dimension > SliceNextDim < D1 , D1 :: Larger > for Slice {
431- fn next_dim ( & self , _: PhantomData < D1 > ) -> PhantomData < D1 :: Larger > {
432- PhantomData
433- }
434- }
435-
436- macro_rules! impl_slicenextdim_for_index_type {
437- ( $index: ty) => {
438- impl <D1 : Dimension > SliceNextDim <D1 , D1 > for $index {
423+ macro_rules! impl_slicenextdim_equal {
424+ ( $self: ty) => {
425+ impl <D1 : Dimension > SliceNextDim <D1 , D1 > for $self {
439426 fn next_dim( & self , _: PhantomData <D1 >) -> PhantomData <D1 > {
440427 PhantomData
441428 }
442429 }
443430 }
444431}
445-
446- impl_slicenextdim_for_index_type ! ( isize ) ;
447- impl_slicenextdim_for_index_type ! ( usize ) ;
448- impl_slicenextdim_for_index_type ! ( i32 ) ;
449-
450- impl < D1 : Dimension , T > SliceNextDim < D1 , D1 :: Larger > for Range < T > {
451- fn next_dim ( & self , _: PhantomData < D1 > ) -> PhantomData < D1 :: Larger > {
452- PhantomData
453- }
454- }
455-
456- impl < D1 : Dimension , T > SliceNextDim < D1 , D1 :: Larger > for RangeFrom < T > {
457- fn next_dim ( & self , _: PhantomData < D1 > ) -> PhantomData < D1 :: Larger > {
458- PhantomData
459- }
460- }
461-
462- impl < D1 : Dimension , T > SliceNextDim < D1 , D1 :: Larger > for RangeTo < T > {
463- fn next_dim ( & self , _: PhantomData < D1 > ) -> PhantomData < D1 :: Larger > {
464- PhantomData
465- }
466- }
467-
468- impl < D1 : Dimension > SliceNextDim < D1 , D1 :: Larger > for RangeFull {
469- fn next_dim ( & self , _: PhantomData < D1 > ) -> PhantomData < D1 :: Larger > {
470- PhantomData
432+ impl_slicenextdim_equal ! ( isize ) ;
433+ impl_slicenextdim_equal ! ( usize ) ;
434+ impl_slicenextdim_equal ! ( i32 ) ;
435+
436+ macro_rules! impl_slicenextdim_larger {
437+ ( ( $( $generics: tt) * ) , $self: ty) => {
438+ impl <D1 : Dimension , $( $generics) ,* > SliceNextDim <D1 , D1 :: Larger > for $self {
439+ fn next_dim( & self , _: PhantomData <D1 >) -> PhantomData <D1 :: Larger > {
440+ PhantomData
441+ }
442+ }
471443 }
472444}
445+ impl_slicenextdim_larger ! ( ( T ) , Range <T >) ;
446+ impl_slicenextdim_larger ! ( ( T ) , RangeInclusive <T >) ;
447+ impl_slicenextdim_larger ! ( ( T ) , RangeFrom <T >) ;
448+ impl_slicenextdim_larger ! ( ( T ) , RangeTo <T >) ;
449+ impl_slicenextdim_larger ! ( ( T ) , RangeToInclusive <T >) ;
450+ impl_slicenextdim_larger ! ( ( ) , RangeFull ) ;
451+ impl_slicenextdim_larger ! ( ( ) , Slice ) ;
473452
474453/// Slice argument constructor.
475454///
0 commit comments