Skip to content

Commit 5eb0e08

Browse files
committed
Implement nth_back for RChunks(Exact)(Mut)
1 parent 2f1bc91 commit 5eb0e08

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

src/libcore/slice/mod.rs

+72
Original file line numberDiff line numberDiff line change
@@ -4643,6 +4643,23 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
46434643
Some(fst)
46444644
}
46454645
}
4646+
4647+
#[inline]
4648+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
4649+
let len = self.len();
4650+
if n >= len {
4651+
self.v = &[];
4652+
None
4653+
} else {
4654+
// can't underflow because `n < len`
4655+
let offset_from_end = (len - 1 - n) * self.chunk_size;
4656+
let end = self.v.len() - offset_from_end;
4657+
let start = end.saturating_sub(self.chunk_size);
4658+
let nth_back = &self.v[start..end];
4659+
self.v = &self.v[end..];
4660+
Some(nth_back)
4661+
}
4662+
}
46464663
}
46474664

46484665
#[stable(feature = "rchunks", since = "1.31.0")]
@@ -4768,6 +4785,24 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
47684785
Some(head)
47694786
}
47704787
}
4788+
4789+
#[inline]
4790+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
4791+
let len = self.len();
4792+
if n >= len {
4793+
self.v = &mut [];
4794+
None
4795+
} else {
4796+
// can't underflow because `n < len`
4797+
let offset_from_end = (len - 1 - n) * self.chunk_size;
4798+
let end = self.v.len() - offset_from_end;
4799+
let start = end.saturating_sub(self.chunk_size);
4800+
let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
4801+
let (_, nth_back) = tmp.split_at_mut(start);
4802+
self.v = tail;
4803+
Some(nth_back)
4804+
}
4805+
}
47714806
}
47724807

47734808
#[stable(feature = "rchunks", since = "1.31.0")]
@@ -4892,6 +4927,24 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
48924927
Some(fst)
48934928
}
48944929
}
4930+
4931+
#[inline]
4932+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
4933+
let len = self.len();
4934+
if n >= len {
4935+
self.v = &[];
4936+
None
4937+
} else {
4938+
// now that we know that `n` corresponds to a chunk,
4939+
// none of these operations can underflow/overflow
4940+
let offset = (len - n) * self.chunk_size;
4941+
let start = self.v.len() - offset;
4942+
let end = start + self.chunk_size;
4943+
let nth_back = &self.v[start..end];
4944+
self.v = &self.v[end..];
4945+
Some(nth_back)
4946+
}
4947+
}
48954948
}
48964949

48974950
#[stable(feature = "rchunks", since = "1.31.0")]
@@ -5010,6 +5063,25 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
50105063
Some(head)
50115064
}
50125065
}
5066+
5067+
#[inline]
5068+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
5069+
let len = self.len();
5070+
if n >= len {
5071+
self.v = &mut [];
5072+
None
5073+
} else {
5074+
// now that we know that `n` corresponds to a chunk,
5075+
// none of these operations can underflow/overflow
5076+
let offset = (len - n) * self.chunk_size;
5077+
let start = self.v.len() - offset;
5078+
let end = start + self.chunk_size;
5079+
let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
5080+
let (_, nth_back) = tmp.split_at_mut(start);
5081+
self.v = tail;
5082+
Some(nth_back)
5083+
}
5084+
}
50135085
}
50145086

50155087
#[stable(feature = "rchunks", since = "1.31.0")]

src/libcore/tests/slice.rs

+52
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,19 @@ fn test_rchunks_nth() {
356356
assert_eq!(c2.next(), None);
357357
}
358358

359+
#[test]
360+
fn test_rchunks_nth_back() {
361+
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
362+
let mut c = v.rchunks(2);
363+
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
364+
assert_eq!(c.next_back().unwrap(), &[4, 5]);
365+
366+
let v2: &[i32] = &[0, 1, 2, 3, 4];
367+
let mut c2 = v2.rchunks(3);
368+
assert_eq!(c2.nth_back(1).unwrap(), &[2, 3, 4]);
369+
assert_eq!(c2.next_back(), None);
370+
}
371+
359372
#[test]
360373
fn test_rchunks_last() {
361374
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
@@ -407,6 +420,19 @@ fn test_rchunks_mut_nth() {
407420
assert_eq!(c2.next(), None);
408421
}
409422

423+
#[test]
424+
fn test_rchunks_mut_nth_back() {
425+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
426+
let mut c = v.rchunks_mut(2);
427+
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
428+
assert_eq!(c.next_back().unwrap(), &[4, 5]);
429+
430+
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
431+
let mut c2 = v2.rchunks_mut(3);
432+
assert_eq!(c2.nth_back(1).unwrap(), &[2, 3, 4]);
433+
assert_eq!(c2.next_back(), None);
434+
}
435+
410436
#[test]
411437
fn test_rchunks_mut_last() {
412438
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
@@ -460,6 +486,19 @@ fn test_rchunks_exact_nth() {
460486
assert_eq!(c2.next(), None);
461487
}
462488

489+
#[test]
490+
fn test_rchunks_exact_nth_back() {
491+
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
492+
let mut c = v.rchunks_exact(2);
493+
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
494+
assert_eq!(c.next_back().unwrap(), &[4, 5]);
495+
496+
let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
497+
let mut c2 = v2.rchunks_exact(3);
498+
assert_eq!(c2.nth_back(1).unwrap(), &[4, 5, 6]);
499+
assert_eq!(c2.next(), None);
500+
}
501+
463502
#[test]
464503
fn test_rchunks_exact_last() {
465504
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
@@ -518,6 +557,19 @@ fn test_rchunks_exact_mut_nth() {
518557
assert_eq!(c2.next(), None);
519558
}
520559

560+
#[test]
561+
fn test_rchunks_exact_mut_nth_back() {
562+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
563+
let mut c = v.rchunks_exact_mut(2);
564+
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
565+
assert_eq!(c.next_back().unwrap(), &[4, 5]);
566+
567+
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6];
568+
let mut c2 = v2.rchunks_exact_mut(3);
569+
assert_eq!(c2.nth_back(1).unwrap(), &[4, 5, 6]);
570+
assert_eq!(c2.next(), None);
571+
}
572+
521573
#[test]
522574
fn test_rchunks_exact_mut_last() {
523575
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)