diff options
| author | bors <bors@rust-lang.org> | 2018-09-22 14:26:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-09-22 14:26:15 +0000 |
| commit | af50e3822c4ceda60445c4a2adbb3bfa480ebd39 (patch) | |
| tree | 34fd72c893b38708f648f92b4222ebc7ea625b9a /src/libcore/slice | |
| parent | e7b5ba8661aa844a06c37f22d7af0afb1807d347 (diff) | |
| parent | 48ec53ccaebe555832114612b6c3f8df183c0a91 (diff) | |
| download | rust-af50e3822c4ceda60445c4a2adbb3bfa480ebd39.tar.gz rust-af50e3822c4ceda60445c4a2adbb3bfa480ebd39.zip | |
Auto merge of #54457 - pietroalbini:rollup, r=pietroalbini
Rollup of 16 pull requests
Successful merges:
- #53652 (define copy_within on slices)
- #54261 (Make `dyn` a keyword in the 2018 edition)
- #54280 (remove (more) CAS API from Atomic* types where not natively supported)
- #54323 (rustbuild: drop color handling)
- #54350 (Support specifying edition in doc test)
- #54370 (Improve handling of type bounds in `bit_set.rs`.)
- #54371 (add -Zui-testing to rustdoc)
- #54374 (Make 'proc_macro::MultiSpan' public.)
- #54402 (Use no_default_libraries for all NetBSD flavors)
- #54409 (Detect `for _ in in bar {}` typo)
- #54412 (add applicability to span_suggestion call)
- #54413 (Add UI test for deref recursion limit printing twice)
- #54415 (parser: Tweak function parameter parsing to avoid rollback on succesfull path)
- #54420 (Compress `Liveness` data some more.)
- #54422 (Simplify slice's first(_mut) and last(_mut) with get)
- #54446 (Unify christianpoveda's emails)
Failed merges:
- #54058 (Introduce the partition_dedup/by/by_key methods for slices)
r? @ghost
Diffstat (limited to 'src/libcore/slice')
| -rw-r--r-- | src/libcore/slice/mod.rs | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index da4a56cfecd..aed9020d9d1 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -119,7 +119,7 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn first(&self) -> Option<&T> { - if self.is_empty() { None } else { Some(&self[0]) } + self.get(0) } /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty. @@ -137,7 +137,7 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn first_mut(&mut self) -> Option<&mut T> { - if self.is_empty() { None } else { Some(&mut self[0]) } + self.get_mut(0) } /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty. @@ -239,7 +239,8 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn last(&self) -> Option<&T> { - if self.is_empty() { None } else { Some(&self[self.len() - 1]) } + let last_idx = self.len().checked_sub(1)?; + self.get(last_idx) } /// Returns a mutable pointer to the last item in the slice. @@ -257,9 +258,8 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn last_mut(&mut self) -> Option<&mut T> { - let len = self.len(); - if len == 0 { return None; } - Some(&mut self[len - 1]) + let last_idx = self.len().checked_sub(1)?; + self.get_mut(last_idx) } /// Returns a reference to an element or subslice depending on the type of @@ -1618,6 +1618,63 @@ impl<T> [T] { } } + /// Copies elements from one part of the slice to another part of itself, + /// using a memmove. + /// + /// `src` is the range within `self` to copy from. `dest` is the starting + /// index of the range within `self` to copy to, which will have the same + /// length as `src`. The two ranges may overlap. The ends of the two ranges + /// must be less than or equal to `self.len()`. + /// + /// # Panics + /// + /// This function will panic if either range exceeds the end of the slice, + /// or if the end of `src` is before the start. + /// + /// # Examples + /// + /// Copying four bytes within a slice: + /// + /// ``` + /// # #![feature(copy_within)] + /// let mut bytes = *b"Hello, World!"; + /// + /// bytes.copy_within(1..5, 8); + /// + /// assert_eq!(&bytes, b"Hello, Wello!"); + /// ``` + #[unstable(feature = "copy_within", issue = "54236")] + pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize) + where + T: Copy, + { + let src_start = match src.start_bound() { + ops::Bound::Included(&n) => n, + ops::Bound::Excluded(&n) => n + .checked_add(1) + .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Unbounded => 0, + }; + let src_end = match src.end_bound() { + ops::Bound::Included(&n) => n + .checked_add(1) + .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Excluded(&n) => n, + ops::Bound::Unbounded => self.len(), + }; + assert!(src_start <= src_end, "src end is before src start"); + assert!(src_end <= self.len(), "src is out of bounds"); + let count = src_end - src_start; + assert!(dest <= self.len() - count, "dest is out of bounds"); + unsafe { + ptr::copy( + self.get_unchecked(src_start), + self.get_unchecked_mut(dest), + count, + ); + } + } + /// Swaps all elements in `self` with those in `other`. /// /// The length of `other` must be the same as `self`. |
