-
Notifications
You must be signed in to change notification settings - Fork 220
Move ExtractIf iterator into its own module #629
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
Merged
alejandro-vaz
merged 5 commits into
servo:v2
from
Kxrma47:refactor/extract-if-iterator-module
Sep 20, 2026
+102
−94
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
f33ca44
Move ExtractIf iterator into its own module
Kxrma47 8afcb7d
Use direct ExtractIf module export
Kxrma47 5b944b6
Match iterator import formatting
Kxrma47 a652d77
Resolve ExtractIf module after Drain merge
Kxrma47 e66016a
Group iterator exports for rustfmt
Kxrma47 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| use crate::{ | ||
| Allocator, | ||
| SmallVec | ||
| }; | ||
|
|
||
| /// An iterator which uses a closure to determine if an element should be | ||
| /// removed. | ||
| /// | ||
| /// Returned from [`SmallVec::extract_if`][1]. | ||
| /// | ||
| /// [1]: struct.SmallVec.html#method.extract_if | ||
| pub struct ExtractIf<'a, T, const N: usize, A: Allocator, F> | ||
| where F: FnMut(&mut T) -> bool | ||
| { | ||
| pub(crate) vec: &'a mut SmallVec<T, N, A>, | ||
| /// The index of the item that will be inspected by the next call to `next`. | ||
| pub(crate) idx: usize, | ||
| /// Elements at and beyond this point will be retained. Must be equal or | ||
| /// smaller than `old_len`. | ||
| pub(crate) end: usize, | ||
| /// The number of items that have been drained (removed) thus far. | ||
| pub(crate) del: usize, | ||
| /// The original length of `vec` prior to draining. | ||
| pub(crate) old_len: usize, | ||
| /// The filter test predicate. | ||
| pub(crate) pred: F | ||
| } | ||
|
alejandro-vaz marked this conversation as resolved.
|
||
|
|
||
| impl<T, const N: usize, A: Allocator, F> core::fmt::Debug for ExtractIf<'_, T, N, A, F> | ||
| where | ||
| F: FnMut(&mut T) -> bool, | ||
| T: core::fmt::Debug | ||
| { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| f.debug_tuple("ExtractIf") | ||
| .field(&self.vec.as_slice()) | ||
| .finish() | ||
| } | ||
| } | ||
|
|
||
| impl<T, F, const N: usize, A: Allocator> Iterator for ExtractIf<'_, T, N, A, F> | ||
| where F: FnMut(&mut T) -> bool | ||
| { | ||
| type Item = T; | ||
|
|
||
| fn next(&mut self) -> Option<T> { | ||
| unsafe { | ||
| while self.idx < self.end { | ||
| let i = self.idx; | ||
| // SAFETY: `i < self.end <= self.old_len` | ||
| let cur = self.vec.as_mut_ptr().add(i); | ||
| let drained = (self.pred)(&mut *cur); | ||
| // Update the index *after* the predicate is called. If the | ||
| // index is updated prior and the predicate | ||
| // panics, the element at this index would be | ||
| // leaked. | ||
| self.idx += 1; | ||
| if drained { | ||
| self.del += 1; | ||
| return Some(core::ptr::read(cur)); | ||
| } else if self.del > 0 { | ||
| // SAFETY: `self.del <= i` therefore `i - self.del` is valid | ||
| core::ptr::copy_nonoverlapping(cur, cur.sub(self.del), 1); | ||
| } | ||
| } | ||
| None | ||
| } | ||
| } | ||
|
|
||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| (0, Some(self.end - self.idx)) | ||
| } | ||
| } | ||
|
|
||
| impl<T, F, const N: usize, A: Allocator> Drop for ExtractIf<'_, T, N, A, F> | ||
| where F: FnMut(&mut T) -> bool | ||
| { | ||
| fn drop(&mut self) { | ||
| unsafe { | ||
| if self.idx < self.old_len && self.del > 0 { | ||
| // This is a pretty messed up state, and there isn't really an | ||
| // obviously right thing to do. We don't want to keep trying | ||
| // to execute `pred`, so we just backshift all the unprocessed | ||
| // elements and tell the vec that they still exist. The | ||
| // backshift is required to prevent a | ||
| // double-drop of the last successfully | ||
| // drained item prior to a panic in the predicate. | ||
| let ptr = self.vec.as_mut_ptr(); | ||
| let src = ptr.add(self.idx); | ||
| let dst = src.sub(self.del); | ||
| let tail_len = self.old_len - self.idx; | ||
| src.copy_to(dst, tail_len); | ||
| } | ||
| self.vec.set_len(self.old_len - self.del); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| pub mod drain; | ||
| pub mod extractif; | ||
|
|
||
| #[cfg(feature = "rayon")] | ||
| mod rayon; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.