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.
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.
12 use ops
::{self, Add, Sub}
;
15 use super::{FusedIterator, TrustedLen}
;
17 /// Objects that can be stepped over in both directions.
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",
24 pub trait Step
: PartialOrd
+ Sized
{
25 /// Steps `self` if possible.
26 fn step(&self, by
: &Self) -> Option
<Self>;
28 /// Returns the number of steps between two step objects. The count is
29 /// inclusive of `start` and exclusive of `end`.
31 /// Returns `None` if it is not possible to calculate `steps_between`
33 fn steps_between(start
: &Self, end
: &Self, by
: &Self) -> Option
<usize>;
35 /// Same as `steps_between`, but with a `by` of 1
36 fn steps_between_by_one(start
: &Self, end
: &Self) -> Option
<usize>;
38 /// Tests whether this step is negative or not (going backwards)
39 fn is_negative(&self) -> bool
;
41 /// Replaces this step with `1`, returning itself
42 fn replace_one(&mut self) -> Self;
44 /// Replaces this step with `0`, returning itself
45 fn replace_zero(&mut self) -> Self;
47 /// Adds one to this step, returning the result
48 fn add_one(&self) -> Self;
50 /// Subtracts one to this step, returning the result
51 fn sub_one(&self) -> Self;
54 macro_rules
! step_impl_unsigned
{
56 #[unstable(feature = "step_trait",
57 reason
= "likely to be replaced by finer-grained traits",
61 fn step(&self, by
: &$t
) -> Option
<$t
> {
62 (*self).checked_add(*by
)
65 #[allow(trivial_numeric_casts)]
66 fn steps_between(start
: &$t
, end
: &$t
, by
: &$t
) -> Option
<usize> {
67 if *by
== 0 { return None; }
69 // Note: We assume $t <= usize here
70 let diff
= (*end
- *start
) as usize;
71 let by
= *by
as usize;
83 fn is_negative(&self) -> bool
{
88 fn replace_one(&mut self) -> Self {
93 fn replace_zero(&mut self) -> Self {
98 fn add_one(&self) -> Self {
103 fn sub_one(&self) -> Self {
108 fn steps_between_by_one(start
: &Self, end
: &Self) -> Option
<usize> {
109 Self::steps_between(start
, end
, &1)
114 macro_rules
! step_impl_signed
{
116 #[unstable(feature = "step_trait",
117 reason
= "likely to be replaced by finer-grained traits",
121 fn step(&self, by
: &$t
) -> Option
<$t
> {
122 (*self).checked_add(*by
)
125 #[allow(trivial_numeric_casts)]
126 fn steps_between(start
: &$t
, end
: &$t
, by
: &$t
) -> Option
<usize> {
127 if *by
== 0 { return None; }
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;
143 diff
= (*start
as isize).wrapping_sub(*end
as isize) as usize;
144 by_u
= (*by
as isize).wrapping_mul(-1) as usize;
147 Some(diff
/ by_u
+ 1)
154 fn is_negative(&self) -> bool
{
159 fn replace_one(&mut self) -> Self {
160 mem
::replace(self, 1)
164 fn replace_zero(&mut self) -> Self {
165 mem
::replace(self, 0)
169 fn add_one(&self) -> Self {
174 fn sub_one(&self) -> Self {
179 fn steps_between_by_one(start
: &Self, end
: &Self) -> Option
<usize> {
180 Self::steps_between(start
, end
, &1)
186 macro_rules
! step_impl_no_between
{
188 #[unstable(feature = "step_trait",
189 reason
= "likely to be replaced by finer-grained traits",
193 fn step(&self, by
: &$t
) -> Option
<$t
> {
194 (*self).checked_add(*by
)
197 fn steps_between(_a
: &$t
, _b
: &$t
, _by
: &$t
) -> Option
<usize> {
202 #[allow(unused_comparisons)]
203 fn is_negative(&self) -> bool
{
208 fn replace_one(&mut self) -> Self {
209 mem
::replace(self, 1)
213 fn replace_zero(&mut self) -> Self {
214 mem
::replace(self, 0)
218 fn add_one(&self) -> Self {
223 fn sub_one(&self) -> Self {
228 fn steps_between_by_one(start
: &Self, end
: &Self) -> Option
<usize> {
229 Self::steps_between(start
, end
, &1)
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
);
247 /// An adapter for stepping range iterators by a custom amount.
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",
255 #[rustc_deprecated(since = "1.19.0",
256 reason
= "replaced by `iter::StepBy`")]
258 pub struct StepBy
<A
, R
> {
263 impl<A
: Step
> ops
::RangeFrom
<A
> {
264 /// Creates an iterator starting at the same point, but stepping by
265 /// the given amount at each iteration.
270 /// #![feature(step_by)]
272 /// let result: Vec<_> = (0..).step_by(2).take(5).collect();
273 /// assert_eq!(result, vec![0, 2, 4, 6, 8]);
276 #[unstable(feature = "step_by", reason = "recent addition",
278 #[rustc_deprecated(since = "1.19.0",
279 reason
= "replaced by `Iterator::step_by`")]
281 pub fn step_by(self, by
: A
) -> StepBy
<A
, Self> {
289 impl<A
: Step
> ops
::Range
<A
> {
290 /// Creates an iterator with the same range, but stepping by the
291 /// given amount at each iteration.
293 /// The resulting iterator handles overflow by stopping.
298 /// #![feature(step_by)]
300 /// let result: Vec<_> = (0..10).step_by(2).collect();
301 /// assert_eq!(result, vec![0, 2, 4, 6, 8]);
304 #[unstable(feature = "step_by", reason = "recent addition",
306 #[rustc_deprecated(since = "1.19.0",
307 reason
= "replaced by `Iterator::step_by`")]
309 pub fn step_by(self, by
: A
) -> StepBy
<A
, Self> {
317 impl<A
: Step
> ops
::RangeInclusive
<A
> {
318 /// Creates an iterator with the same range, but stepping by the
319 /// given amount at each iteration.
321 /// The resulting iterator handles overflow by stopping.
326 /// #![feature(step_by, inclusive_range_syntax)]
328 /// let result: Vec<_> = (0...10).step_by(2).collect();
329 /// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]);
331 #[unstable(feature = "step_by", reason = "recent addition",
333 #[rustc_deprecated(since = "1.19.0",
334 reason
= "replaced by `Iterator::step_by`")]
336 pub fn step_by(self, by
: A
) -> StepBy
<A
, Self> {
344 #[unstable(feature = "step_by", reason = "recent addition",
347 impl<A
> Iterator
for StepBy
<A
, ops
::RangeFrom
<A
>> where
349 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>
354 fn next(&mut self) -> Option
<A
> {
355 let mut n
= &self.range
.start
+ &self.step_by
;
356 mem
::swap(&mut n
, &mut self.range
.start
);
361 fn size_hint(&self) -> (usize, Option
<usize>) {
362 (usize::MAX
, None
) // Too bad we can't specify an infinite lower bound
366 #[unstable(feature = "fused", issue = "35602")]
368 impl<A
> FusedIterator
for StepBy
<A
, ops
::RangeFrom
<A
>>
369 where A
: Clone
, for<'a
> &'a A
: Add
<&'a A
, Output
= A
> {}
371 #[unstable(feature = "step_by", reason = "recent addition",
374 impl<A
: Step
+ Clone
> Iterator
for StepBy
<A
, ops
::Range
<A
>> {
378 fn next(&mut self) -> Option
<A
> {
379 let rev
= self.step_by
.is_negative();
380 if (rev
&& self.range
.start
> self.range
.end
) ||
381 (!rev
&& self.range
.start
< self.range
.end
)
383 match self.range
.start
.step(&self.step_by
) {
385 mem
::swap(&mut self.range
.start
, &mut n
);
389 let mut n
= self.range
.end
.clone();
390 mem
::swap(&mut self.range
.start
, &mut n
);
400 fn size_hint(&self) -> (usize, Option
<usize>) {
401 match Step
::steps_between(&self.range
.start
,
404 Some(hint
) => (hint
, Some(hint
)),
410 #[unstable(feature = "fused", issue = "35602")]
412 impl<A
: Step
+ Clone
> FusedIterator
for StepBy
<A
, ops
::Range
<A
>> {}
414 #[unstable(feature = "inclusive_range",
415 reason
= "recently added, follows RFC",
418 impl<A
: Step
+ Clone
> Iterator
for StepBy
<A
, ops
::RangeInclusive
<A
>> {
422 fn next(&mut self) -> Option
<A
> {
423 let rev
= self.step_by
.is_negative();
425 if (rev
&& self.range
.start
>= self.range
.end
) ||
426 (!rev
&& self.range
.start
<= self.range
.end
)
428 match self.range
.start
.step(&self.step_by
) {
430 Some(mem
::replace(&mut self.range
.start
, n
))
433 let last
= self.range
.start
.replace_one();
434 self.range
.end
.replace_zero();
435 self.step_by
.replace_one();
446 fn size_hint(&self) -> (usize, Option
<usize>) {
447 match Step
::steps_between(&self.range
.start
,
450 Some(hint
) => (hint
.saturating_add(1), hint
.checked_add(1)),
456 #[unstable(feature = "fused", issue = "35602")]
458 impl<A
: Step
+ Clone
> FusedIterator
for StepBy
<A
, ops
::RangeInclusive
<A
>> {}
460 macro_rules
! range_exact_iter_impl
{
462 #[stable(feature = "rust1", since = "1.0.0")]
463 impl ExactSizeIterator
for ops
::Range
<$t
> { }
467 macro_rules
! range_incl_exact_iter_impl
{
469 #[unstable(feature = "inclusive_range",
470 reason
= "recently added, follows RFC",
472 impl ExactSizeIterator
for ops
::RangeInclusive
<$t
> { }
476 macro_rules
! range_trusted_len_impl
{
478 #[unstable(feature = "trusted_len", issue = "37572")]
479 unsafe impl TrustedLen
for ops
::Range
<$t
> { }
483 macro_rules
! range_incl_trusted_len_impl
{
485 #[unstable(feature = "inclusive_range",
486 reason
= "recently added, follows RFC",
488 unsafe impl TrustedLen
for ops
::RangeInclusive
<$t
> { }
492 #[stable(feature = "rust1", since = "1.0.0")]
493 impl<A
: Step
> Iterator
for ops
::Range
<A
> where
494 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>
499 fn next(&mut self) -> Option
<A
> {
500 if self.start
< self.end
{
501 let mut n
= self.start
.add_one();
502 mem
::swap(&mut n
, &mut self.start
);
510 fn size_hint(&self) -> (usize, Option
<usize>) {
511 match Step
::steps_between_by_one(&self.start
, &self.end
) {
512 Some(hint
) => (hint
, Some(hint
)),
518 // These macros generate `ExactSizeIterator` impls for various range types.
519 // Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
520 // because they cannot guarantee having a length <= usize::MAX, which is
521 // required by ExactSizeIterator.
522 range_exact_iter_impl
!(usize u8 u16 u32 isize i8 i16 i32);
523 range_incl_exact_iter_impl
!(u8 u16 i8 i16);
525 // These macros generate `TrustedLen` impls.
527 // They need to guarantee that .size_hint() is either exact, or that
528 // the upper bound is None when it does not fit the type limits.
529 range_trusted_len_impl
!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
530 range_incl_trusted_len_impl
!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
532 #[stable(feature = "rust1", since = "1.0.0")]
533 impl<A
: Step
+ Clone
> DoubleEndedIterator
for ops
::Range
<A
> where
534 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>,
535 for<'a
> &'a A
: Sub
<&'a A
, Output
= A
>
538 fn next_back(&mut self) -> Option
<A
> {
539 if self.start
< self.end
{
540 self.end
= self.end
.sub_one();
541 Some(self.end
.clone())
548 #[unstable(feature = "fused", issue = "35602")]
549 impl<A
> FusedIterator
for ops
::Range
<A
>
550 where A
: Step
, for<'a
> &'a A
: Add
<&'a A
, Output
= A
> {}
552 #[stable(feature = "rust1", since = "1.0.0")]
553 impl<A
: Step
> Iterator
for ops
::RangeFrom
<A
> where
554 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>
559 fn next(&mut self) -> Option
<A
> {
560 let mut n
= self.start
.add_one();
561 mem
::swap(&mut n
, &mut self.start
);
566 fn size_hint(&self) -> (usize, Option
<usize>) {
571 #[unstable(feature = "fused", issue = "35602")]
572 impl<A
> FusedIterator
for ops
::RangeFrom
<A
>
573 where A
: Step
, for<'a
> &'a A
: Add
<&'a A
, Output
= A
> {}
575 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
576 impl<A
: Step
> Iterator
for ops
::RangeInclusive
<A
> where
577 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>
582 fn next(&mut self) -> Option
<A
> {
583 use cmp
::Ordering
::*;
585 match self.start
.partial_cmp(&self.end
) {
587 let n
= self.start
.add_one();
588 Some(mem
::replace(&mut self.start
, n
))
591 let last
= self.start
.replace_one();
592 self.end
.replace_zero();
600 fn size_hint(&self) -> (usize, Option
<usize>) {
601 if !(self.start
<= self.end
) {
605 match Step
::steps_between_by_one(&self.start
, &self.end
) {
606 Some(hint
) => (hint
.saturating_add(1), hint
.checked_add(1)),
612 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
613 impl<A
: Step
> DoubleEndedIterator
for ops
::RangeInclusive
<A
> where
614 for<'a
> &'a A
: Add
<&'a A
, Output
= A
>,
615 for<'a
> &'a A
: Sub
<&'a A
, Output
= A
>
618 fn next_back(&mut self) -> Option
<A
> {
619 use cmp
::Ordering
::*;
621 match self.start
.partial_cmp(&self.end
) {
623 let n
= self.end
.sub_one();
624 Some(mem
::replace(&mut self.end
, n
))
627 let last
= self.end
.replace_zero();
628 self.start
.replace_one();
636 #[unstable(feature = "fused", issue = "35602")]
637 impl<A
> FusedIterator
for ops
::RangeInclusive
<A
>
638 where A
: Step
, for<'a
> &'a A
: Add
<&'a A
, Output
= A
> {}