diff options
| author | bors <bors@rust-lang.org> | 2015-07-13 23:47:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-13 23:47:06 +0000 |
| commit | dd46cf8b22c39a74b786361e00af22314a32b196 (patch) | |
| tree | ef42015a6a4e59fe77648d41ca5a79f4e0cdb21f /src/libcore | |
| parent | 72483f58e355c6ec9016cbaba4d9b8d3adbd3867 (diff) | |
| parent | 3226858e500fa70b46c18d1accedc60060f2bbc0 (diff) | |
| download | rust-dd46cf8b22c39a74b786361e00af22314a32b196.tar.gz rust-dd46cf8b22c39a74b786361e00af22314a32b196.zip | |
Auto merge of #26241 - SimonSapin:derefmut-for-string, r=alexcrichton
See https://github.com/rust-lang/rfcs/issues/1157
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/str/mod.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index bd6e1a4063a..7e4c2ba3be8 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1116,6 +1116,23 @@ mod traits { } } + /// Returns a mutable slice of the given string from the byte range + /// [`begin`..`end`). + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::Range<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_mut_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } + } + } + /// Returns a slice of the string from the beginning to byte /// `end`. /// @@ -1138,6 +1155,21 @@ mod traits { } } + /// Returns a mutable slice of the string from the beginning to byte + /// `end`. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeTo<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_mut_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } + } + } + /// Returns a slice of the string from `begin` to its end. /// /// Equivalent to `self[begin .. self.len()]`. @@ -1159,6 +1191,21 @@ mod traits { } } + /// Returns a slice of the string from `begin` to its end. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeFrom<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + let len = self.len(); + unsafe { self.slice_mut_unchecked(index.start, len) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeFull> for str { type Output = str; @@ -1168,6 +1215,14 @@ mod traits { self } } + + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeFull> for str { + #[inline] + fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str { + self + } + } } /// Methods for string slices @@ -1204,6 +1259,7 @@ pub trait StrExt { fn char_len(&self) -> usize; fn slice_chars<'a>(&'a self, begin: usize, end: usize) -> &'a str; unsafe fn slice_unchecked<'a>(&'a self, begin: usize, end: usize) -> &'a str; + unsafe fn slice_mut_unchecked<'a>(&'a mut self, begin: usize, end: usize) -> &'a mut str; fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool; fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool where P::Searcher: ReverseSearcher<'a>; @@ -1223,6 +1279,7 @@ pub trait StrExt { where P::Searcher: ReverseSearcher<'a>; fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>; fn split_at(&self, mid: usize) -> (&str, &str); + fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str); fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>; fn subslice_offset(&self, inner: &str) -> usize; fn as_ptr(&self) -> *const u8; @@ -1380,6 +1437,14 @@ impl StrExt for str { } #[inline] + unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str { + mem::transmute(Slice { + data: self.as_ptr().offset(begin as isize), + len: end - begin, + }) + } + + #[inline] fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { pat.is_prefix_of(self) } @@ -1527,6 +1592,20 @@ impl StrExt for str { } } + fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(mid) { + let len = self.len(); + unsafe { + let self2: &mut str = mem::transmute_copy(&self); + (self.slice_mut_unchecked(0, mid), + self2.slice_mut_unchecked(mid, len)) + } + } else { + slice_error_fail(self, 0, mid) + } + } + #[inline] fn slice_shift_char(&self) -> Option<(char, &str)> { if self.is_empty() { |
