Open Norlock opened 9 months ago
If I want to use a mutable vector to iterate over the same vector (log n).
Doesn't look like log(n) to me at all. It's quadratic.
impl<T: std::fmt::Debug> Splitting<T> for Vec<T> { fn split_item_mut(&mut self, idx: usize) -> (&mut T, OtherIterMut<T>) {
Debug
shouldn't be required
impl<T: std::fmt::Debug> Splitting<T> for Vec<T> { fn split_item_mut(&mut self, idx: usize) -> (&mut T, OtherIterMut<T>) {
Debug
shouldn't be required
It shouldn't, I copied it from my code and forgot to remove. Anyway outside of some mistakes I made I think the idea is useful.
Does this make sense for many iterators? It seems more like a new variant of the slice-splitting methods, if it returned (&mut [T], &mut T, &mut [T])
as mentioned in alternatives.
Yes I think that's also fine, but I think in most use cases (my guess) the first variant is more direct. But it doesn't allow multiple iterators so the alternative is maybe better
As I said in https://internals.rust-lang.org/t/create-iterator-function-in-std-libs-split-item-mut/19880/2?u=scottmcm, this shouldn't return Chain
, and definitely shouldn't include a type alias.
I agree with cuviper that this is a slice-to-slices split thing, not something that should have anything to do with iterators.
Ok I updated the issue and swapped the main solution with the alternative one.
I'll also throw my support behind this on the condition that it is a slice split function rather than some sort of iterator related function.
I've written a function similar to this several times in my own code because I wanted the slice before, the reference to the value at an index, and the slice after.
My mind was pulled particularly to an exercise I wrote when I was learning rust, this part of a quicksort implementation:
let (lower_portion, pivot_plus_upper) = slice.split_at_mut(pivot);
let (_pivot_portion, upper_portion) = pivot_plus_upper.split_at_mut(1);
quicksort_subproblem(lower_portion);
quicksort_subproblem(upper_portion);
Anyways, the way I envision the API is more like this:
pub fn split_around_mut(&mut self) -> Option<(&mut [T], &mut T, &mut [T])>
pub fn split_around(&self) -> Option<(&[T], &T, &[T])>
It must return None for the case of an empty slice.
Proposal
Problem statement
If I want to use a mutable vector to iterate over the same vector. I can't do this without the borrow checker starts to complain about the vector already being borrowed. There is no user friendly alternative / ergonomic solution for this problem. A possible problem:
Motivating examples or use cases
This is something the borrow checker won't allow. Of course there are options to fix this like updating the index in the vector immediately or using something like swap_remove, both solutions are not very ergonomic / user friendly in my opinion.
Solution sketch
A possible solution is:
And to use it:
Of course this isn't a boundry safe API so you can think of returning the "item" in the tuple as an Option.
Alternatives
And to use it:
Links and related work
Also posted on: https://internals.rust-lang.org/t/create-iterator-function-in-std-libs-split-item-mut/19880