]> git.lizzy.rs Git - rust.git/blob - src/libcore/iter/range.rs
rustdoc: Hide `self: Box<Self>` in list of deref methods
[rust.git] / src / libcore / iter / range.rs
1 // Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use mem;
12 use ops::{self, Add, Sub};
13 use usize;
14
15 use super::{FusedIterator, TrustedLen};
16
17 /// Objects that can be stepped over in both directions.
18 ///
19 /// The `steps_between` function provides a way to efficiently compare
20 /// two `Step` objects.
21 #[unstable(feature = "step_trait",
22            reason = "likely to be replaced by finer-grained traits",
23            issue = "42168")]
24 pub trait Step: PartialOrd + Sized {
25     /// Steps `self` if possible.
26     fn step(&self, by: &Self) -> Option<Self>;
27
28     /// Returns the number of steps between two step objects. The count is
29     /// inclusive of `start` and exclusive of `end`.
30     ///
31     /// Returns `None` if it is not possible to calculate `steps_between`
32     /// without overflow.
33     fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
34
35     /// Same as `steps_between`, but with a `by` of 1
36     fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize>;
37
38     /// Tests whether this step is negative or not (going backwards)
39     fn is_negative(&self) -> bool;
40
41     /// Replaces this step with `1`, returning itself
42     fn replace_one(&mut self) -> Self;
43
44     /// Replaces this step with `0`, returning itself
45     fn replace_zero(&mut self) -> Self;
46
47     /// Adds one to this step, returning the result
48     fn add_one(&self) -> Self;
49
50     /// Subtracts one to this step, returning the result
51     fn sub_one(&self) -> Self;
52 }
53
54 macro_rules! step_impl_unsigned {
55     ($($t:ty)*) => ($(
56         #[unstable(feature = "step_trait",
57                    reason = "likely to be replaced by finer-grained traits",
58                    issue = "42168")]
59         impl Step for $t {
60             #[inline]
61             fn step(&self, by: &$t) -> Option<$t> {
62                 (*self).checked_add(*by)
63             }
64             #[inline]
65             #[allow(trivial_numeric_casts)]
66             fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
67                 if *by == 0 { return None; }
68                 if *start < *end {
69                     // Note: We assume $t <= usize here
70                     let diff = (*end - *start) as usize;
71                     let by = *by as usize;
72                     if diff % by > 0 {
73                         Some(diff / by + 1)
74                     } else {
75                         Some(diff / by)
76                     }
77                 } else {
78                     Some(0)
79                 }
80             }
81
82             #[inline]
83             fn is_negative(&self) -> bool {
84                 false
85             }
86
87             #[inline]
88             fn replace_one(&mut self) -> Self {
89                 mem::replace(self, 1)
90             }
91
92             #[inline]
93             fn replace_zero(&mut self) -> Self {
94                 mem::replace(self, 0)
95             }
96
97             #[inline]
98             fn add_one(&self) -> Self {
99                 Add::add(*self, 1)
100             }
101
102             #[inline]
103             fn sub_one(&self) -> Self {
104                 Sub::sub(*self, 1)
105             }
106
107             #[inline]
108             fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
109                 Self::steps_between(start, end, &1)
110             }
111         }
112     )*)
113 }
114 macro_rules! step_impl_signed {
115     ($($t:ty)*) => ($(
116         #[unstable(feature = "step_trait",
117                    reason = "likely to be replaced by finer-grained traits",
118                    issue = "42168")]
119         impl Step for $t {
120             #[inline]
121             fn step(&self, by: &$t) -> Option<$t> {
122                 (*self).checked_add(*by)
123             }
124             #[inline]
125             #[allow(trivial_numeric_casts)]
126             fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
127                 if *by == 0 { return None; }
128                 let diff: usize;
129                 let by_u: usize;
130                 if *by > 0 {
131                     if *start >= *end {
132                         return Some(0);
133                     }
134                     // Note: We assume $t <= isize here
135                     // Use .wrapping_sub and cast to usize to compute the
136                     // difference that may not fit inside the range of isize.
137                     diff = (*end as isize).wrapping_sub(*start as isize) as usize;
138                     by_u = *by as usize;
139                 } else {
140                     if *start <= *end {
141                         return Some(0);
142                     }
143                     diff = (*start as isize).wrapping_sub(*end as isize) as usize;
144                     by_u = (*by as isize).wrapping_mul(-1) as usize;
145                 }
146                 if diff % by_u > 0 {
147                     Some(diff / by_u + 1)
148                 } else {
149                     Some(diff / by_u)
150                 }
151             }
152
153             #[inline]
154             fn is_negative(&self) -> bool {
155                 *self < 0
156             }
157
158             #[inline]
159             fn replace_one(&mut self) -> Self {
160                 mem::replace(self, 1)
161             }
162
163             #[inline]
164             fn replace_zero(&mut self) -> Self {
165                 mem::replace(self, 0)
166             }
167
168             #[inline]
169             fn add_one(&self) -> Self {
170                 Add::add(*self, 1)
171             }
172
173             #[inline]
174             fn sub_one(&self) -> Self {
175                 Sub::sub(*self, 1)
176             }
177
178             #[inline]
179             fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
180                 Self::steps_between(start, end, &1)
181             }
182         }
183     )*)
184 }
185
186 macro_rules! step_impl_no_between {
187     ($($t:ty)*) => ($(
188         #[unstable(feature = "step_trait",
189                    reason = "likely to be replaced by finer-grained traits",
190                    issue = "42168")]
191         impl Step for $t {
192             #[inline]
193             fn step(&self, by: &$t) -> Option<$t> {
194                 (*self).checked_add(*by)
195             }
196             #[inline]
197             fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
198                 None
199             }
200
201             #[inline]
202             #[allow(unused_comparisons)]
203             fn is_negative(&self) -> bool {
204                 *self < 0
205             }
206
207             #[inline]
208             fn replace_one(&mut self) -> Self {
209                 mem::replace(self, 1)
210             }
211
212             #[inline]
213             fn replace_zero(&mut self) -> Self {
214                 mem::replace(self, 0)
215             }
216
217             #[inline]
218             fn add_one(&self) -> Self {
219                 Add::add(*self, 1)
220             }
221
222             #[inline]
223             fn sub_one(&self) -> Self {
224                 Sub::sub(*self, 1)
225             }
226
227             #[inline]
228             fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
229                 Self::steps_between(start, end, &1)
230             }
231         }
232     )*)
233 }
234
235 step_impl_unsigned!(usize u8 u16 u32);
236 step_impl_signed!(isize i8 i16 i32);
237 #[cfg(target_pointer_width = "64")]
238 step_impl_unsigned!(u64);
239 #[cfg(target_pointer_width = "64")]
240 step_impl_signed!(i64);
241 // If the target pointer width is not 64-bits, we
242 // assume here that it is less than 64-bits.
243 #[cfg(not(target_pointer_width = "64"))]
244 step_impl_no_between!(u64 i64);
245 step_impl_no_between!(u128 i128);
246
247 /// An adapter for stepping range iterators by a custom amount.
248 ///
249 /// The resulting iterator handles overflow by stopping. The `A`
250 /// parameter is the type being iterated over, while `R` is the range
251 /// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`.
252 #[derive(Clone, Debug)]
253 #[unstable(feature = "step_by", reason = "recent addition",
254            issue = "27741")]
255 pub struct StepBy<A, R> {
256     step_by: A,
257     range: R,
258 }
259
260 impl<A: Step> ops::RangeFrom<A> {
261     /// Creates an iterator starting at the same point, but stepping by
262     /// the given amount at each iteration.
263     ///
264     /// # Examples
265     ///
266     /// ```
267     /// #![feature(step_by)]
268     /// fn main() {
269     ///     let result: Vec<_> = (0..).step_by(2).take(5).collect();
270     ///     assert_eq!(result, vec![0, 2, 4, 6, 8]);
271     /// }
272     /// ```
273     #[unstable(feature = "step_by", reason = "recent addition",
274                issue = "27741")]
275     pub fn step_by(self, by: A) -> StepBy<A, Self> {
276         StepBy {
277             step_by: by,
278             range: self
279         }
280     }
281 }
282
283 impl<A: Step> ops::Range<A> {
284     /// Creates an iterator with the same range, but stepping by the
285     /// given amount at each iteration.
286     ///
287     /// The resulting iterator handles overflow by stopping.
288     ///
289     /// # Examples
290     ///
291     /// ```
292     /// #![feature(step_by)]
293     /// fn main() {
294     ///     let result: Vec<_> = (0..10).step_by(2).collect();
295     ///     assert_eq!(result, vec![0, 2, 4, 6, 8]);
296     /// }
297     /// ```
298     #[unstable(feature = "step_by", reason = "recent addition",
299                issue = "27741")]
300     pub fn step_by(self, by: A) -> StepBy<A, Self> {
301         StepBy {
302             step_by: by,
303             range: self
304         }
305     }
306 }
307
308 impl<A: Step> ops::RangeInclusive<A> {
309     /// Creates an iterator with the same range, but stepping by the
310     /// given amount at each iteration.
311     ///
312     /// The resulting iterator handles overflow by stopping.
313     ///
314     /// # Examples
315     ///
316     /// ```
317     /// #![feature(step_by, inclusive_range_syntax)]
318     ///
319     /// let result: Vec<_> = (0...10).step_by(2).collect();
320     /// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]);
321     /// ```
322     #[unstable(feature = "step_by", reason = "recent addition",
323                issue = "27741")]
324     pub fn step_by(self, by: A) -> StepBy<A, Self> {
325         StepBy {
326             step_by: by,
327             range: self
328         }
329     }
330 }
331
332 #[unstable(feature = "step_by", reason = "recent addition",
333            issue = "27741")]
334 impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
335     A: Clone,
336     for<'a> &'a A: Add<&'a A, Output = A>
337 {
338     type Item = A;
339
340     #[inline]
341     fn next(&mut self) -> Option<A> {
342         let mut n = &self.range.start + &self.step_by;
343         mem::swap(&mut n, &mut self.range.start);
344         Some(n)
345     }
346
347     #[inline]
348     fn size_hint(&self) -> (usize, Option<usize>) {
349         (usize::MAX, None) // Too bad we can't specify an infinite lower bound
350     }
351 }
352
353 #[unstable(feature = "fused", issue = "35602")]
354 impl<A> FusedIterator for StepBy<A, ops::RangeFrom<A>>
355     where A: Clone, for<'a> &'a A: Add<&'a A, Output = A> {}
356
357 #[unstable(feature = "step_by", reason = "recent addition",
358            issue = "27741")]
359 impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
360     type Item = A;
361
362     #[inline]
363     fn next(&mut self) -> Option<A> {
364         let rev = self.step_by.is_negative();
365         if (rev && self.range.start > self.range.end) ||
366            (!rev && self.range.start < self.range.end)
367         {
368             match self.range.start.step(&self.step_by) {
369                 Some(mut n) => {
370                     mem::swap(&mut self.range.start, &mut n);
371                     Some(n)
372                 },
373                 None => {
374                     let mut n = self.range.end.clone();
375                     mem::swap(&mut self.range.start, &mut n);
376                     Some(n)
377                 }
378             }
379         } else {
380             None
381         }
382     }
383
384     #[inline]
385     fn size_hint(&self) -> (usize, Option<usize>) {
386         match Step::steps_between(&self.range.start,
387                                   &self.range.end,
388                                   &self.step_by) {
389             Some(hint) => (hint, Some(hint)),
390             None       => (0, None)
391         }
392     }
393 }
394
395 #[unstable(feature = "fused", issue = "35602")]
396 impl<A: Step + Clone> FusedIterator for StepBy<A, ops::Range<A>> {}
397
398 #[unstable(feature = "inclusive_range",
399            reason = "recently added, follows RFC",
400            issue = "28237")]
401 impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
402     type Item = A;
403
404     #[inline]
405     fn next(&mut self) -> Option<A> {
406         let rev = self.step_by.is_negative();
407
408         if (rev && self.range.start >= self.range.end) ||
409            (!rev && self.range.start <= self.range.end)
410         {
411             match self.range.start.step(&self.step_by) {
412                 Some(n) => {
413                     Some(mem::replace(&mut self.range.start, n))
414                 },
415                 None => {
416                     let last = self.range.start.replace_one();
417                     self.range.end.replace_zero();
418                     self.step_by.replace_one();
419                     Some(last)
420                 },
421             }
422         }
423         else {
424             None
425         }
426     }
427
428     #[inline]
429     fn size_hint(&self) -> (usize, Option<usize>) {
430         match Step::steps_between(&self.range.start,
431                                   &self.range.end,
432                                   &self.step_by) {
433             Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
434             None       => (0, None)
435         }
436     }
437 }
438
439 #[unstable(feature = "fused", issue = "35602")]
440 impl<A: Step + Clone> FusedIterator for StepBy<A, ops::RangeInclusive<A>> {}
441
442 macro_rules! range_exact_iter_impl {
443     ($($t:ty)*) => ($(
444         #[stable(feature = "rust1", since = "1.0.0")]
445         impl ExactSizeIterator for ops::Range<$t> { }
446     )*)
447 }
448
449 macro_rules! range_incl_exact_iter_impl {
450     ($($t:ty)*) => ($(
451         #[unstable(feature = "inclusive_range",
452                    reason = "recently added, follows RFC",
453                    issue = "28237")]
454         impl ExactSizeIterator for ops::RangeInclusive<$t> { }
455     )*)
456 }
457
458 macro_rules! range_trusted_len_impl {
459     ($($t:ty)*) => ($(
460         #[unstable(feature = "trusted_len", issue = "37572")]
461         unsafe impl TrustedLen for ops::Range<$t> { }
462     )*)
463 }
464
465 macro_rules! range_incl_trusted_len_impl {
466     ($($t:ty)*) => ($(
467         #[unstable(feature = "inclusive_range",
468                    reason = "recently added, follows RFC",
469                    issue = "28237")]
470         unsafe impl TrustedLen for ops::RangeInclusive<$t> { }
471     )*)
472 }
473
474 #[stable(feature = "rust1", since = "1.0.0")]
475 impl<A: Step> Iterator for ops::Range<A> where
476     for<'a> &'a A: Add<&'a A, Output = A>
477 {
478     type Item = A;
479
480     #[inline]
481     fn next(&mut self) -> Option<A> {
482         if self.start < self.end {
483             let mut n = self.start.add_one();
484             mem::swap(&mut n, &mut self.start);
485             Some(n)
486         } else {
487             None
488         }
489     }
490
491     #[inline]
492     fn size_hint(&self) -> (usize, Option<usize>) {
493         match Step::steps_between_by_one(&self.start, &self.end) {
494             Some(hint) => (hint, Some(hint)),
495             None => (0, None)
496         }
497     }
498 }
499
500 // These macros generate `ExactSizeIterator` impls for various range types.
501 // Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
502 // because they cannot guarantee having a length <= usize::MAX, which is
503 // required by ExactSizeIterator.
504 range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
505 range_incl_exact_iter_impl!(u8 u16 i8 i16);
506
507 // These macros generate `TrustedLen` impls.
508 //
509 // They need to guarantee that .size_hint() is either exact, or that
510 // the upper bound is None when it does not fit the type limits.
511 range_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
512 range_incl_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
513
514 #[stable(feature = "rust1", since = "1.0.0")]
515 impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
516     for<'a> &'a A: Add<&'a A, Output = A>,
517     for<'a> &'a A: Sub<&'a A, Output = A>
518 {
519     #[inline]
520     fn next_back(&mut self) -> Option<A> {
521         if self.start < self.end {
522             self.end = self.end.sub_one();
523             Some(self.end.clone())
524         } else {
525             None
526         }
527     }
528 }
529
530 #[unstable(feature = "fused", issue = "35602")]
531 impl<A> FusedIterator for ops::Range<A>
532     where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
533
534 #[stable(feature = "rust1", since = "1.0.0")]
535 impl<A: Step> Iterator for ops::RangeFrom<A> where
536     for<'a> &'a A: Add<&'a A, Output = A>
537 {
538     type Item = A;
539
540     #[inline]
541     fn next(&mut self) -> Option<A> {
542         let mut n = self.start.add_one();
543         mem::swap(&mut n, &mut self.start);
544         Some(n)
545     }
546
547     #[inline]
548     fn size_hint(&self) -> (usize, Option<usize>) {
549         (usize::MAX, None)
550     }
551 }
552
553 #[unstable(feature = "fused", issue = "35602")]
554 impl<A> FusedIterator for ops::RangeFrom<A>
555     where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
556
557 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
558 impl<A: Step> Iterator for ops::RangeInclusive<A> where
559     for<'a> &'a A: Add<&'a A, Output = A>
560 {
561     type Item = A;
562
563     #[inline]
564     fn next(&mut self) -> Option<A> {
565         use cmp::Ordering::*;
566
567         match self.start.partial_cmp(&self.end) {
568             Some(Less) => {
569                 let n = self.start.add_one();
570                 Some(mem::replace(&mut self.start, n))
571             },
572             Some(Equal) => {
573                 let last = self.start.replace_one();
574                 self.end.replace_zero();
575                 Some(last)
576             },
577             _ => None,
578         }
579     }
580
581     #[inline]
582     fn size_hint(&self) -> (usize, Option<usize>) {
583         if !(self.start <= self.end) {
584             return (0, Some(0));
585         }
586
587         match Step::steps_between_by_one(&self.start, &self.end) {
588             Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
589             None => (0, None),
590         }
591     }
592 }
593
594 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
595 impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
596     for<'a> &'a A: Add<&'a A, Output = A>,
597     for<'a> &'a A: Sub<&'a A, Output = A>
598 {
599     #[inline]
600     fn next_back(&mut self) -> Option<A> {
601         use cmp::Ordering::*;
602
603         match self.start.partial_cmp(&self.end) {
604             Some(Less) => {
605                 let n = self.end.sub_one();
606                 Some(mem::replace(&mut self.end, n))
607             },
608             Some(Equal) => {
609                 let last = self.end.replace_zero();
610                 self.start.replace_one();
611                 Some(last)
612             },
613             _ => None,
614         }
615     }
616 }
617
618 #[unstable(feature = "fused", issue = "35602")]
619 impl<A> FusedIterator for ops::RangeInclusive<A>
620     where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}