Skip to content

Commit

Permalink
Rollup merge of rust-lang#61671 - koalatux:nth-back-range, r=KodrAus
Browse files Browse the repository at this point in the history
implement nth_back for Range(Inclusive)

This is part of  rust-lang#54054.
  • Loading branch information
Centril authored Jun 12, 2019
2 parents 9f22708 + 8590074 commit 3a8dc44
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,19 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
None
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<A> {
if let Some(minus_n) = self.end.sub_usize(n) {
if minus_n > self.start {
self.end = minus_n.sub_one();
return Some(self.end.clone())
}
}

self.end = self.start.clone();
None
}
}

#[stable(feature = "fused", since = "1.26.0")]
Expand Down Expand Up @@ -438,6 +451,34 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
})
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<A> {
self.compute_is_empty();
if self.is_empty.unwrap_or_default() {
return None;
}

if let Some(minus_n) = self.end.sub_usize(n) {
use crate::cmp::Ordering::*;

match minus_n.partial_cmp(&self.start) {
Some(Greater) => {
self.is_empty = Some(false);
self.end = minus_n.sub_one();
return Some(minus_n);
}
Some(Equal) => {
self.is_empty = Some(true);
return Some(minus_n);
}
_ => {}
}
}

self.is_empty = Some(true);
None
}

#[inline]
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
Expand Down
37 changes: 37 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,23 @@ fn test_range_nth() {
assert_eq!(r, 20..20);
}

#[test]
fn test_range_nth_back() {
assert_eq!((10..15).nth_back(0), Some(14));
assert_eq!((10..15).nth_back(1), Some(13));
assert_eq!((10..15).nth_back(4), Some(10));
assert_eq!((10..15).nth_back(5), None);
assert_eq!((-120..80_i8).nth_back(199), Some(-120));

let mut r = 10..20;
assert_eq!(r.nth_back(2), Some(17));
assert_eq!(r, 10..17);
assert_eq!(r.nth_back(2), Some(14));
assert_eq!(r, 10..14);
assert_eq!(r.nth_back(10), None);
assert_eq!(r, 10..10);
}

#[test]
fn test_range_from_nth() {
assert_eq!((10..).nth(0), Some(10));
Expand Down Expand Up @@ -1714,6 +1731,26 @@ fn test_range_inclusive_nth() {
assert_eq!(ExactSizeIterator::is_empty(&r), true);
}

#[test]
fn test_range_inclusive_nth_back() {
assert_eq!((10..=15).nth_back(0), Some(15));
assert_eq!((10..=15).nth_back(1), Some(14));
assert_eq!((10..=15).nth_back(5), Some(10));
assert_eq!((10..=15).nth_back(6), None);
assert_eq!((-120..=80_i8).nth_back(200), Some(-120));

let mut r = 10_u8..=20;
assert_eq!(r.nth_back(2), Some(18));
assert_eq!(r, 10..=17);
assert_eq!(r.nth_back(2), Some(15));
assert_eq!(r, 10..=14);
assert_eq!(r.is_empty(), false);
assert_eq!(ExactSizeIterator::is_empty(&r), false);
assert_eq!(r.nth_back(10), None);
assert_eq!(r.is_empty(), true);
assert_eq!(ExactSizeIterator::is_empty(&r), true);
}

#[test]
fn test_range_step() {
#![allow(deprecated)]
Expand Down

0 comments on commit 3a8dc44

Please sign in to comment.