about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorwizAmit <amitforfriends_dns@yahoo.com>2019-05-14 13:28:43 +0530
committerwizAmit <amitforfriends_dns@yahoo.com>2019-05-14 13:28:43 +0530
commit16223e4bea1ecb087c60d2ac1aeb16c7b7033d52 (patch)
tree63056c070164e4bdb151690227eb1a2d70e9d980 /src/libcore
parentaff83c80dd162b43a301e2bea73762cc4560f0f3 (diff)
downloadrust-16223e4bea1ecb087c60d2ac1aeb16c7b7033d52.tar.gz
rust-16223e4bea1ecb087c60d2ac1aeb16c7b7033d52.zip
new implementation for nth_back for chunks
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/slice/mod.rs27
-rw-r--r--src/libcore/tests/slice.rs6
2 files changed, 27 insertions, 6 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 00dbe7104d1..72a54c5ce82 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -4155,15 +4155,32 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
 
     #[inline]
     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
-        let (end, overflow) = self.v.len().overflowing_sub(n * self.chunk_size);
+        let remainder = match self.v.len().checked_rem(self.chunk_size) {
+            Some(res) => res,
+            None => 0,
+        };
+
+        let sub_chunk_size = if remainder != 0 { remainder } else { self.chunk_size };
+
+        let safe_sub = match n.checked_mul(sub_chunk_size) {
+            Some(res) => res,
+            None => 0,
+        };
+
+        let (end, overflow) = self.v.len().overflowing_sub(safe_sub);
         if overflow {
-            self.v = &mut [];
+            self.v=  &[];
             None
         } else {
-            let start = match end.checked_sub(self.chunk_size) {
-                Some(res) => cmp::min(self.v.len(), res),
-                None => 0,
+            let start = if n == 0 {
+                self.v.len() - sub_chunk_size
+            } else {
+                match end.checked_sub(self.chunk_size) {
+                    Some(res) => res,
+                    None => 0,
+                }
             };
+
             let nth_back = &self.v[start..end];
             self.v = &self.v[..start];
             Some(nth_back)
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index edea405fad7..cf2602f3210 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -144,7 +144,7 @@ fn test_chunks_nth_back() {
 
     let v2: &[i32] = &[0, 1, 2, 3, 4];
     let mut c2 = v2.chunks(3);
-    assert_eq!(c2.nth_back(1).unwrap(), &[0, 1]);
+    assert_eq!(c2.nth_back(1).unwrap(), &[0, 1, 2]);
     assert_eq!(c2.next(), None);
     assert_eq!(c2.next_back(), None);
 
@@ -152,6 +152,10 @@ fn test_chunks_nth_back() {
     let mut c3 = v3.chunks(10);
     assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]);
     assert_eq!(c3.next(), None);
+
+    let v4: &[i32] = &[0, 1, 2];
+    let mut c4 = v4.chunks(10);
+    assert_eq!(c4.nth_back(1_000_000_000usize), None);
 }
 
 #[test]