diff options
| author | bors <bors@rust-lang.org> | 2017-08-15 16:21:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-08-15 16:21:28 +0000 |
| commit | 82be83cf744611a016fb09ae1afbffc04b3ed2e1 (patch) | |
| tree | e7054196a3c1077869c05473d3ef605fb7a47b6a /src/liballoc/string.rs | |
| parent | 1b08e0f231cd30719c25a5992f1d9bb27ea02b61 (diff) | |
| parent | 618ac89d256adca97518742db2ad2759c4f5fc72 (diff) | |
| download | rust-82be83cf744611a016fb09ae1afbffc04b3ed2e1.tar.gz rust-82be83cf744611a016fb09ae1afbffc04b3ed2e1.zip | |
Auto merge of #43500 - murarth:string-retain, r=alexcrichton
Add method `String::retain` Behaves like `Vec::retain`, accepting a predicate `FnMut(char) -> bool` and reducing the string to only characters for which the predicate returns `true`.
Diffstat (limited to 'src/liballoc/string.rs')
| -rw-r--r-- | src/liballoc/string.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 3ed5d2df1ab..a913d833a90 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1061,6 +1061,57 @@ impl String { ch } + /// Retains only the characters specified by the predicate. + /// + /// In other words, remove all characters `c` such that `f(c)` returns `false`. + /// This method operates in place and preserves the order of the retained + /// characters. + /// + /// # Examples + /// + /// ``` + /// #![feature(string_retain)] + /// + /// let mut s = String::from("f_o_ob_ar"); + /// + /// s.retain(|c| c != '_'); + /// + /// assert_eq!(s, "foobar"); + /// ``` + #[inline] + #[unstable(feature = "string_retain", issue = "43874")] + pub fn retain<F>(&mut self, mut f: F) + where F: FnMut(char) -> bool + { + let len = self.len(); + let mut del_bytes = 0; + let mut idx = 0; + + while idx < len { + let ch = unsafe { + self.slice_unchecked(idx, len).chars().next().unwrap() + }; + let ch_len = ch.len_utf8(); + + if !f(ch) { + del_bytes += ch_len; + } else if del_bytes > 0 { + unsafe { + ptr::copy(self.vec.as_ptr().offset(idx as isize), + self.vec.as_mut_ptr().offset((idx - del_bytes) as isize), + ch_len); + } + } + + // Point idx to the next char + idx += ch_len; + } + + if del_bytes > 0 { + unsafe { self.vec.set_len(len - del_bytes); } + } + } + /// Inserts a character into this `String` at a byte position. /// /// This is an `O(n)` operation as it requires copying every element in the |
