There are some quite complex to do correctly algorithms that are implemented as part of Vec
: retain
, retain_mut
, drain
. And there are few crates that widely used and implement custom version of Vec
, like ArrayVec
and SmallVec
.
Currently they either copy-paste implementations from std like ArrayVec
or just implement much less effecient version like SmallVec
. In both cases, there is a concern that those implementations would lag behind bugfixes or improvements from std
with time.
I suggest to make standard implementations available for users by implementing a trait and specific functions that implement those algorithms.
My first draft of the API:
pub mod VecAlgorithms {
pub unsafe trait VecLike<Element: Sized> {
fn capacity(&self) -> usize;
fn len(&self) -> usize;
fn as_mut_ptr(&mut self) -> core::ptr::NonNull<Element>;
unsafe fn set_len(&mut self, new_len: usize);
}
pub fn retain_mut_impl<Element, V, FKeepIf>(vec: &mut V, mut predicate: FKeepIf)
where
Element: Sized,
V: VecLike<Element> + ?Sized,
FKeepIf: FnMut(&mut Element) -> bool,
{
// Canonical implementations moves here
}
pub fn dedup_by_impl<Element, V, FIsSame>(vec: &mut V, mut is_same_bucket: FIsSame)
where
Element: Sized,
V: VecLike<Element> + ?Sized,
FIsSame: FnMut(&mut Element, &mut Element) -> bool,
{
// Canonical implementation moves here
}
}
This would allow user crates to implement their own custom versions of Vec by reusing thoroughly tested and rigorously optimized algorithms used in implementation of standard Vec and greatly simplify their code.