]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/slice/mod.rs
wip nth_back on chunks
[rust.git] / src / libcore / slice / mod.rs
index a7a0dbd89d77285d8a12ad31841beb083ed2404a..54c5285bc495cdeb830f6310eacefe9f7feca250 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 //! Slice management and manipulation.
 //!
 //! For more details see [`std::slice`].
@@ -357,6 +359,10 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     /// The caller must ensure that the slice outlives the pointer this
     /// function returns, or else it will end up pointing to garbage.
     ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
+    ///
     /// Modifying the container referenced by this slice may cause its buffer
     /// to be reallocated, which would also make any pointers to it invalid.
     ///
@@ -372,6 +378,8 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     ///     }
     /// }
     /// ```
+    ///
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub const fn as_ptr(&self) -> *const T {
@@ -524,7 +532,7 @@ pub fn reverse(&mut self) {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn iter(&self) -> Iter<T> {
+    pub fn iter(&self) -> Iter<'_, T> {
         unsafe {
             let ptr = self.as_ptr();
             assume(!ptr.is_null());
@@ -556,7 +564,7 @@ pub fn iter(&self) -> Iter<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn iter_mut(&mut self) -> IterMut<T> {
+    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
         unsafe {
             let ptr = self.as_mut_ptr();
             assume(!ptr.is_null());
@@ -603,7 +611,7 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn windows(&self, size: usize) -> Windows<T> {
+    pub fn windows(&self, size: usize) -> Windows<'_, T> {
         assert!(size != 0);
         Windows { v: self, size }
     }
@@ -637,7 +645,7 @@ pub fn windows(&self, size: usize) -> Windows<T> {
     /// [`rchunks`]: #method.rchunks
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
+    pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
         assert!(chunk_size != 0);
         Chunks { v: self, chunk_size }
     }
@@ -675,7 +683,7 @@ pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
     /// [`rchunks_mut`]: #method.rchunks_mut
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
+    pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
         assert!(chunk_size != 0);
         ChunksMut { v: self, chunk_size }
     }
@@ -712,7 +720,7 @@ pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
     /// [`rchunks_exact`]: #method.rchunks_exact
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[inline]
-    pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<T> {
+    pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let len = self.len() - rem;
@@ -757,7 +765,7 @@ pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<T> {
     /// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[inline]
-    pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
+    pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let len = self.len() - rem;
@@ -794,7 +802,7 @@ pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
     /// [`chunks`]: #method.chunks
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[inline]
-    pub fn rchunks(&self, chunk_size: usize) -> RChunks<T> {
+    pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
         assert!(chunk_size != 0);
         RChunks { v: self, chunk_size }
     }
@@ -832,7 +840,7 @@ pub fn rchunks(&self, chunk_size: usize) -> RChunks<T> {
     /// [`chunks_mut`]: #method.chunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[inline]
-    pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<T> {
+    pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
         assert!(chunk_size != 0);
         RChunksMut { v: self, chunk_size }
     }
@@ -871,7 +879,7 @@ pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<T> {
     /// [`chunks_exact`]: #method.chunks_exact
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[inline]
-    pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<T> {
+    pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let (fst, snd) = self.split_at(rem);
@@ -916,7 +924,7 @@ pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<T> {
     /// [`chunks_exact_mut`]: #method.chunks_exact_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[inline]
-    pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<T> {
+    pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let (fst, snd) = self.split_at_mut(rem);
@@ -1042,7 +1050,7 @@ pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn split<F>(&self, pred: F) -> Split<T, F>
+    pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         Split {
@@ -1067,7 +1075,7 @@ pub fn split<F>(&self, pred: F) -> Split<T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
+    pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         SplitMut { v: self, pred, finished: false }
@@ -1102,7 +1110,7 @@ pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
     /// ```
     #[stable(feature = "slice_rsplit", since = "1.27.0")]
     #[inline]
-    pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
+    pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         RSplit { inner: self.split(pred) }
@@ -1127,7 +1135,7 @@ pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
     ///
     #[stable(feature = "slice_rsplit", since = "1.27.0")]
     #[inline]
-    pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
+    pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         RSplitMut { inner: self.split_mut(pred) }
@@ -1154,7 +1162,7 @@ pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
+    pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         SplitN {
@@ -1184,7 +1192,7 @@ pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
+    pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         SplitNMut {
@@ -1217,7 +1225,7 @@ pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
+    pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         RSplitN {
@@ -1248,7 +1256,7 @@ pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, F>
+    pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
         where F: FnMut(&T) -> bool
     {
         RSplitNMut {
@@ -3284,7 +3292,7 @@ pub struct Iter<'a, T: 'a> {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("Iter")
             .field(&self.as_slice())
             .finish()
@@ -3386,7 +3394,7 @@ pub struct IterMut<'a, T: 'a> {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("IterMut")
             .field(&self.make_slice())
             .finish()
@@ -3493,7 +3501,7 @@ pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Split")
             .field("v", &self.v)
             .field("finished", &self.finished)
@@ -3539,6 +3547,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
             (1, Some(self.v.len() + 1))
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3584,7 +3597,7 @@ pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitMut")
             .field("v", &self.v)
             .field("finished", &self.finished)
@@ -3637,6 +3650,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
             (1, Some(self.v.len() + 1))
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3681,7 +3699,7 @@ pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
 impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("RSplit")
             .field("v", &self.inner.v)
             .field("finished", &self.inner.finished)
@@ -3702,6 +3720,11 @@ fn next(&mut self) -> Option<&'a [T]> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -3737,7 +3760,7 @@ pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
 impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("RSplitMut")
             .field("v", &self.inner.v)
             .field("finished", &self.inner.finished)
@@ -3766,6 +3789,11 @@ fn next(&mut self) -> Option<&'a mut [T]> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -3823,7 +3851,7 @@ pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitN")
             .field("inner", &self.inner)
             .finish()
@@ -3845,7 +3873,7 @@ pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("RSplitN")
             .field("inner", &self.inner)
             .finish()
@@ -3866,7 +3894,7 @@ pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitNMut")
             .field("inner", &self.inner)
             .finish()
@@ -3888,7 +3916,7 @@ pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
 impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P> where P: FnMut(&T) -> bool {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("RSplitNMut")
             .field("inner", &self.inner)
             .finish()
@@ -4150,6 +4178,22 @@ fn next_back(&mut self) -> Option<&'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")]