-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add method String::retain
#43500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add method String::retain
#43500
Conversation
r? @BurntSushi (rust_highfive has picked a reviewer for you, use r? to override) |
The motivation for this method is similar to that of |
src/liballoc/string.rs
Outdated
#[inline] | ||
#[unstable(feature = "string_retain", issue = "0")] | ||
pub fn retain<F>(&mut self, mut f: F) | ||
where F: FnMut(char) -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In HashMap::retain, we used F: FnMut(&K, &mut V) -> bool
, in case we need to mutate the value in iteration. @alexcrichton also thinks it is better if we can improve Vec::retain to be F: FnMut(&mut T) -> bool
, though it is too late to do this. So I guess it could be better if we use F: FnMut(&mut char)->bool
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Vec
and HashMap
, it's trivial to pass a &mut
instead of &
. For String
, however, the code would have to be changed to write the decoded char
back into the buffer. Because the new char
could be larger than the original, it would significantly increase the complexity and perhaps require the allocation of a second buffer to manage it. I don't think that's the right direction to go in, in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed that we can't just simply modify chars in place. It is not worth to do this. Please ignore my comments.
I've pinged @BurntSushi on irc for a review - we'll check in now and again to make sure this gets reviewed soon @murarth! |
Sorry I missed this! This seems like a reasonable API to have to me. With that said, it does seem like cc @rust-lang/libs |
@BurntSushi: I wrote a
Here's the full implementation: https://gist.github.com/murarth/ac22d58c75602ceb1cc5f79e87474c37 Edit: Updated benchmark results. Ha ha, forgot to compile the benchmarks with |
Hi @BurntSushi - are you reviewing this? Just a friendly ping to keep this on your radar. |
ping for review @BurntSushi @rust-lang/libs ! |
Ah sorry for the delay @murarth! I think that not having |
Behaves like `Vec::retain`, accepting a predicate `FnMut(char) -> bool` and reducing the string to only characters for which the predicate returns `true`.
@alexcrichton: Created tracking issue #43874 and updated the code. |
|
||
while idx < len { | ||
let ch = unsafe { | ||
self.slice_unchecked(idx, len).chars().next().unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a self.slice_unchecked(idx, len).chars().next().unwrap() followed by a ch.len_utf8() generating a small enough amount of code for the optimizer to optimize away? Or is it better to use/add something leaner that gets compiled faster?
📌 Commit 618ac89 has been approved by |
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`.
☀️ Test successful - status-appveyor, status-travis |
Behaves like
Vec::retain
, accepting a predicateFnMut(char) -> bool
and reducing the string to only characters for which the predicate
returns
true
.