From 4d9b9e9038102ada95d1898d303038803d752f62 Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Fri, 26 Apr 2019 19:53:18 +0530 Subject: [PATCH 1/9] wip nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 16 ++++++++++++++++ src/libcore/tests/slice.rs | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 8731f48675356..049d38c158ce5 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4152,6 +4152,22 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) { + let (end, overflow) = self.v.len().overflowing_sub(n); + if end < self.v.len() || overflow { + self.v = &[]; + None + } else { + let start = match end.checked_sub(self.chunk_size) { + Some(sum) => cmp::min(self.v.len(), sum), + None => self.v.len(), + }; + let nth = &self.v[start..end]; + self.v = &self.v[end..]; + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index acf6b03791f01..0233b96d3a72d 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -134,6 +134,19 @@ fn test_chunks_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); + + 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.next(), None); +} + #[test] fn test_chunks_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From 73ca8bc140d4b0935ecb0199ea65723ec6a6791f Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Wed, 1 May 2019 23:34:07 +0530 Subject: [PATCH 2/9] hopefully working nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 17 +++++++++-------- src/libcore/tests/slice.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 049d38c158ce5..00dbe7104d1a4 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4154,18 +4154,19 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { } #[inline] - fn nth_back(&mut self, n: usize) { - let (end, overflow) = self.v.len().overflowing_sub(n); - if end < self.v.len() || overflow { - self.v = &[]; + fn nth_back(&mut self, n: usize) -> Option { + let (end, overflow) = self.v.len().overflowing_sub(n * self.chunk_size); + if overflow { + self.v = &mut []; None } else { let start = match end.checked_sub(self.chunk_size) { - Some(sum) => cmp::min(self.v.len(), sum), - None => self.v.len(), + Some(res) => cmp::min(self.v.len(), res), + None => 0, }; - let nth = &self.v[start..end]; - self.v = &self.v[end..]; + 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 0233b96d3a72d..edea405fad791 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -139,12 +139,19 @@ fn test_chunks_nth_back() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let mut c = v.chunks(2); assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); - assert_eq!(c.next().unwrap(), &[4, 5]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); 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.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + let mut c3 = v3.chunks(10); + assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]); + assert_eq!(c3.next(), None); } #[test] From 02a148dba261439626c5020a7cbb15e690521e87 Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Fri, 26 Apr 2019 19:53:18 +0530 Subject: [PATCH 3/9] wip nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 16 ++++++++++++++++ src/libcore/tests/slice.rs | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 8731f48675356..049d38c158ce5 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4152,6 +4152,22 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) { + let (end, overflow) = self.v.len().overflowing_sub(n); + if end < self.v.len() || overflow { + self.v = &[]; + None + } else { + let start = match end.checked_sub(self.chunk_size) { + Some(sum) => cmp::min(self.v.len(), sum), + None => self.v.len(), + }; + let nth = &self.v[start..end]; + self.v = &self.v[end..]; + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index acf6b03791f01..0233b96d3a72d 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -134,6 +134,19 @@ fn test_chunks_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); + + 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.next(), None); +} + #[test] fn test_chunks_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From aff83c80dd162b43a301e2bea73762cc4560f0f3 Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Wed, 1 May 2019 23:34:07 +0530 Subject: [PATCH 4/9] hopefully working nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 17 +++++++++-------- src/libcore/tests/slice.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 049d38c158ce5..00dbe7104d1a4 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4154,18 +4154,19 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { } #[inline] - fn nth_back(&mut self, n: usize) { - let (end, overflow) = self.v.len().overflowing_sub(n); - if end < self.v.len() || overflow { - self.v = &[]; + fn nth_back(&mut self, n: usize) -> Option { + let (end, overflow) = self.v.len().overflowing_sub(n * self.chunk_size); + if overflow { + self.v = &mut []; None } else { let start = match end.checked_sub(self.chunk_size) { - Some(sum) => cmp::min(self.v.len(), sum), - None => self.v.len(), + Some(res) => cmp::min(self.v.len(), res), + None => 0, }; - let nth = &self.v[start..end]; - self.v = &self.v[end..]; + 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 0233b96d3a72d..edea405fad791 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -139,12 +139,19 @@ fn test_chunks_nth_back() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let mut c = v.chunks(2); assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); - assert_eq!(c.next().unwrap(), &[4, 5]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); 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.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + let mut c3 = v3.chunks(10); + assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]); + assert_eq!(c3.next(), None); } #[test] From 16223e4bea1ecb087c60d2ac1aeb16c7b7033d52 Mon Sep 17 00:00:00 2001 From: wizAmit Date: Tue, 14 May 2019 13:28:43 +0530 Subject: [PATCH 5/9] new implementation for nth_back for chunks --- src/libcore/slice/mod.rs | 27 ++++++++++++++++++++++----- src/libcore/tests/slice.rs | 6 +++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 00dbe7104d1a4..72a54c5ce82d0 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 { - 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 edea405fad791..cf2602f3210f1 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] From dc82626262605665bbcea8f24925442e48dc897c Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Fri, 26 Apr 2019 19:53:18 +0530 Subject: [PATCH 6/9] wip nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 16 ++++++++++++++++ src/libcore/tests/slice.rs | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index d06d107d32a41..54c5285bc495c 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4178,6 +4178,22 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) { + let (end, overflow) = self.v.len().overflowing_sub(n); + if end < self.v.len() || overflow { + self.v = &[]; + None + } else { + let start = match end.checked_sub(self.chunk_size) { + Some(sum) => cmp::min(self.v.len(), sum), + None => self.v.len(), + }; + let nth = &self.v[start..end]; + self.v = &self.v[end..]; + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index acf6b03791f01..0233b96d3a72d 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -134,6 +134,19 @@ fn test_chunks_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); + + 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.next(), None); +} + #[test] fn test_chunks_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From 2080b86566358dad8cb8c967e321a172a69c49f7 Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Wed, 1 May 2019 23:34:07 +0530 Subject: [PATCH 7/9] hopefully working nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 17 +++++++++-------- src/libcore/tests/slice.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 54c5285bc495c..b138ae3449f87 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4180,18 +4180,19 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { } #[inline] - fn nth_back(&mut self, n: usize) { - let (end, overflow) = self.v.len().overflowing_sub(n); - if end < self.v.len() || overflow { - self.v = &[]; + fn nth_back(&mut self, n: usize) -> Option { + let (end, overflow) = self.v.len().overflowing_sub(n * self.chunk_size); + if overflow { + self.v = &mut []; None } else { let start = match end.checked_sub(self.chunk_size) { - Some(sum) => cmp::min(self.v.len(), sum), - None => self.v.len(), + Some(res) => cmp::min(self.v.len(), res), + None => 0, }; - let nth = &self.v[start..end]; - self.v = &self.v[end..]; + 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 0233b96d3a72d..edea405fad791 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -139,12 +139,19 @@ fn test_chunks_nth_back() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let mut c = v.chunks(2); assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); - assert_eq!(c.next().unwrap(), &[4, 5]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); 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.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + let mut c3 = v3.chunks(10); + assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]); + assert_eq!(c3.next(), None); } #[test] From 29a103daa92bb3607fd4cd34169d4ff6170987fa Mon Sep 17 00:00:00 2001 From: "@amit.chandra" <@amit.chandra> Date: Fri, 26 Apr 2019 19:53:18 +0530 Subject: [PATCH 8/9] wip nth_back on chunks Signed-off-by: wizAmit --- src/libcore/slice/mod.rs | 17 ----------------- src/libcore/tests/slice.rs | 19 ------------------- 2 files changed, 36 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index b138ae3449f87..d06d107d32a41 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4178,23 +4178,6 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { Some(snd) } } - - #[inline] - fn nth_back(&mut self, n: usize) -> Option { - let (end, overflow) = self.v.len().overflowing_sub(n * self.chunk_size); - if overflow { - self.v = &mut []; - None - } else { - let start = match end.checked_sub(self.chunk_size) { - Some(res) => cmp::min(self.v.len(), res), - None => 0, - }; - let nth_back = &self.v[start..end]; - self.v = &self.v[..start]; - Some(nth_back) - } - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index edea405fad791..1cba4b38382a4 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -134,25 +134,6 @@ fn test_chunks_nth() { assert_eq!(c2.next(), None); } -#[test] -fn test_chunks_nth_back() { - let v: &[i32] = &[0, 1, 2, 3, 4, 5]; - let mut c = v.chunks(2); - assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); - assert_eq!(c.next().unwrap(), &[0, 1]); - assert_eq!(c.next(), None); - - 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.next(), None); - assert_eq!(c2.next_back(), None); - - let v3: &[i32] = &[0, 1, 2, 3, 4]; - let mut c3 = v3.chunks(10); - assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]); - assert_eq!(c3.next(), None); -} #[test] fn test_chunks_last() { From 9309447397ffcc2f427f850c1a7df8af2c682169 Mon Sep 17 00:00:00 2001 From: wizAmit Date: Wed, 22 May 2019 22:27:30 +0530 Subject: [PATCH 9/9] succint implementation --- src/libcore/slice/mod.rs | 18 ++++++++++++++++++ src/libcore/tests/slice.rs | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index d06d107d32a41..8862c0c1cefa4 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4178,6 +4178,24 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + self.v = &[]; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = match start.checked_add(self.chunk_size) { + Some(res) => cmp::min(res, self.v.len()), + None => self.v.len(), + }; + let nth_back = &self.v[start..end]; + self.v = &self.v[..start]; + Some(nth_back) + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 1cba4b38382a4..a4cb0c42044b0 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -134,6 +134,30 @@ fn test_chunks_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); + + let v2: &[i32] = &[0, 1, 2, 3, 4]; + let mut c2 = v2.chunks(3); + assert_eq!(c2.nth_back(1).unwrap(), &[0, 1, 2]); + assert_eq!(c2.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + 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] fn test_chunks_last() {