Skip to content

Commit 3a8dc44

Browse files
authored
Rollup merge of #61671 - koalatux:nth-back-range, r=KodrAus
implement nth_back for Range(Inclusive) This is part of #54054.
2 parents 9f22708 + 8590074 commit 3a8dc44

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

src/libcore/iter/range.rs

+41
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
281281
None
282282
}
283283
}
284+
285+
#[inline]
286+
fn nth_back(&mut self, n: usize) -> Option<A> {
287+
if let Some(minus_n) = self.end.sub_usize(n) {
288+
if minus_n > self.start {
289+
self.end = minus_n.sub_one();
290+
return Some(self.end.clone())
291+
}
292+
}
293+
294+
self.end = self.start.clone();
295+
None
296+
}
284297
}
285298

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

454+
#[inline]
455+
fn nth_back(&mut self, n: usize) -> Option<A> {
456+
self.compute_is_empty();
457+
if self.is_empty.unwrap_or_default() {
458+
return None;
459+
}
460+
461+
if let Some(minus_n) = self.end.sub_usize(n) {
462+
use crate::cmp::Ordering::*;
463+
464+
match minus_n.partial_cmp(&self.start) {
465+
Some(Greater) => {
466+
self.is_empty = Some(false);
467+
self.end = minus_n.sub_one();
468+
return Some(minus_n);
469+
}
470+
Some(Equal) => {
471+
self.is_empty = Some(true);
472+
return Some(minus_n);
473+
}
474+
_ => {}
475+
}
476+
}
477+
478+
self.is_empty = Some(true);
479+
None
480+
}
481+
441482
#[inline]
442483
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
443484
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>

src/libcore/tests/iter.rs

+37
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,23 @@ fn test_range_nth() {
16571657
assert_eq!(r, 20..20);
16581658
}
16591659

1660+
#[test]
1661+
fn test_range_nth_back() {
1662+
assert_eq!((10..15).nth_back(0), Some(14));
1663+
assert_eq!((10..15).nth_back(1), Some(13));
1664+
assert_eq!((10..15).nth_back(4), Some(10));
1665+
assert_eq!((10..15).nth_back(5), None);
1666+
assert_eq!((-120..80_i8).nth_back(199), Some(-120));
1667+
1668+
let mut r = 10..20;
1669+
assert_eq!(r.nth_back(2), Some(17));
1670+
assert_eq!(r, 10..17);
1671+
assert_eq!(r.nth_back(2), Some(14));
1672+
assert_eq!(r, 10..14);
1673+
assert_eq!(r.nth_back(10), None);
1674+
assert_eq!(r, 10..10);
1675+
}
1676+
16601677
#[test]
16611678
fn test_range_from_nth() {
16621679
assert_eq!((10..).nth(0), Some(10));
@@ -1714,6 +1731,26 @@ fn test_range_inclusive_nth() {
17141731
assert_eq!(ExactSizeIterator::is_empty(&r), true);
17151732
}
17161733

1734+
#[test]
1735+
fn test_range_inclusive_nth_back() {
1736+
assert_eq!((10..=15).nth_back(0), Some(15));
1737+
assert_eq!((10..=15).nth_back(1), Some(14));
1738+
assert_eq!((10..=15).nth_back(5), Some(10));
1739+
assert_eq!((10..=15).nth_back(6), None);
1740+
assert_eq!((-120..=80_i8).nth_back(200), Some(-120));
1741+
1742+
let mut r = 10_u8..=20;
1743+
assert_eq!(r.nth_back(2), Some(18));
1744+
assert_eq!(r, 10..=17);
1745+
assert_eq!(r.nth_back(2), Some(15));
1746+
assert_eq!(r, 10..=14);
1747+
assert_eq!(r.is_empty(), false);
1748+
assert_eq!(ExactSizeIterator::is_empty(&r), false);
1749+
assert_eq!(r.nth_back(10), None);
1750+
assert_eq!(r.is_empty(), true);
1751+
assert_eq!(ExactSizeIterator::is_empty(&r), true);
1752+
}
1753+
17171754
#[test]
17181755
fn test_range_step() {
17191756
#![allow(deprecated)]

0 commit comments

Comments
 (0)