6
6
// option. This file may not be copied, modified, or distributed
7
7
// except according to those terms.
8
8
use error:: { ShapeError , ErrorKind } ;
9
- use std:: ops:: { Deref , Range , RangeFrom , RangeFull , RangeTo } ;
9
+ use std:: ops:: { Deref , Range , RangeFrom , RangeFull , RangeInclusive , RangeTo , RangeToInclusive } ;
10
10
use std:: fmt;
11
11
use std:: marker:: PhantomData ;
12
12
use super :: Dimension ;
13
13
14
14
/// A slice (range with step size).
15
15
///
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.
18
19
///
19
20
/// See also the [`s![]`](macro.s.html) macro.
20
21
///
@@ -66,58 +67,6 @@ impl Slice {
66
67
}
67
68
}
68
69
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
-
121
70
/// A slice (range with step) or an index.
122
71
///
123
72
/// See also the [`s![]`](macro.s!.html) macro for a convenient way to create a
@@ -144,9 +93,9 @@ impl From<RangeFull> for Slice {
144
93
/// The macro equivalent is `s![a..;-1]`.
145
94
#[ derive( Debug , PartialEq , Eq , Hash ) ]
146
95
pub 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.
150
99
Slice {
151
100
start : isize ,
152
101
end : Option < isize > ,
@@ -219,64 +168,83 @@ impl fmt::Display for SliceOrIndex {
219
168
}
220
169
}
221
170
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 {
236
174
#[ 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
+ }
239
181
}
240
182
}
241
183
242
- impl From <Range <$index>> for SliceOrIndex {
184
+ impl From <RangeInclusive <$index>> for $self {
243
185
#[ 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 ) } ,
248
191
step: 1 ,
249
192
}
250
193
}
251
194
}
252
195
253
- impl From <RangeFrom <$index>> for SliceOrIndex {
196
+ impl From <RangeFrom <$index>> for $self {
254
197
#[ inline]
255
- fn from( r: RangeFrom <$index>) -> SliceOrIndex {
256
- SliceOrIndex :: Slice {
198
+ fn from( r: RangeFrom <$index>) -> $self {
199
+ $constructor {
257
200
start: r. start as isize ,
258
201
end: None ,
259
202
step: 1 ,
260
203
}
261
204
}
262
205
}
263
206
264
- impl From <RangeTo <$index>> for SliceOrIndex {
207
+ impl From <RangeTo <$index>> for $self {
265
208
#[ inline]
266
- fn from( r: RangeTo <$index>) -> SliceOrIndex {
267
- SliceOrIndex :: Slice {
209
+ fn from( r: RangeTo <$index>) -> $self {
210
+ $constructor {
268
211
start: 0 ,
269
212
end: Some ( r. end as isize ) ,
270
213
step: 1 ,
271
214
}
272
215
}
273
216
}
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
+ } ;
275
230
}
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 ) ;
276
237
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
+ }
280
248
281
249
impl From < RangeFull > for SliceOrIndex {
282
250
#[ inline]
@@ -289,6 +257,31 @@ impl From<RangeFull> for SliceOrIndex {
289
257
}
290
258
}
291
259
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
+
292
285
/// Represents all of the necessary information to perform a slice.
293
286
///
294
287
/// The type `T` is typically `[SliceOrIndex; n]`, `[SliceOrIndex]`, or
@@ -427,49 +420,35 @@ pub trait SliceNextDim<D1, D2> {
427
420
fn next_dim ( & self , PhantomData < D1 > ) -> PhantomData < D2 > ;
428
421
}
429
422
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 {
439
426
fn next_dim( & self , _: PhantomData <D1 >) -> PhantomData <D1 > {
440
427
PhantomData
441
428
}
442
429
}
443
430
}
444
431
}
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
+ }
471
443
}
472
444
}
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 ) ;
473
452
474
453
/// Slice argument constructor.
475
454
///
0 commit comments