usecrate::ule::*; usecrate::varzerovec::owned::VarZeroVecOwned; usecrate::vecs::{FlexZeroSlice, FlexZeroVec, FlexZeroVecOwned, VarZeroVecFormat}; usecrate::{VarZeroSlice, VarZeroVec}; usecrate::{ZeroSlice, ZeroVec}; use alloc::boxed::Box; use alloc::vec::Vec; use core::cmp::Ordering; use core::mem; use core::ops::Range;
/// Trait abstracting over [`ZeroVec`] and [`VarZeroVec`], for use in [`ZeroMap`](super::ZeroMap). **You /// should not be implementing or calling this trait directly.** /// /// The T type is the type received by [`Self::zvl_binary_search()`], as well as the one used /// for human-readable serialization. /// /// Methods are prefixed with `zvl_*` to avoid clashes with methods on the types themselves pubtrait ZeroVecLike<T: ?Sized> { /// The type returned by `Self::get()` type GetType: ?Sized + 'static; /// A fully borrowed version of this type SliceVariant: ZeroVecLike<T, GetType = Self::GetType> + ?Sized;
/// Search for a key in a sorted vector, returns `Ok(index)` if found, /// returns `Err(insert_index)` if not found, where `insert_index` is the /// index where it should be inserted to maintain sort order. fn zvl_binary_search(&self, k: &T) -> Result<usize, usize> where
T: Ord; /// Search for a key within a certain range in a sorted vector. /// Returns `None` if the range is out of bounds, and /// `Ok` or `Err` in the same way as `zvl_binary_search`. /// Indices are returned relative to the start of the range. fn zvl_binary_search_in_range(
&self,
k: &T,
range: Range<usize>,
) -> Option<Result<usize, usize>> where
T: Ord;
/// Search for a key in a sorted vector by a predicate, returns `Ok(index)` if found, /// returns `Err(insert_index)` if not found, where `insert_index` is the /// index where it should be inserted to maintain sort order. fn zvl_binary_search_by(&self, predicate: impl FnMut(&T) -> Ordering) -> Result<usize, usize>; /// Search for a key within a certain range in a sorted vector by a predicate. /// Returns `None` if the range is out of bounds, and /// `Ok` or `Err` in the same way as `zvl_binary_search`. /// Indices are returned relative to the start of the range. fn zvl_binary_search_in_range_by(
&self,
predicate: impl FnMut(&T) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>>;
/// Get element at `index` fn zvl_get(&self, index: usize) -> Option<&Self::GetType>; /// The length of this vector fn zvl_len(&self) -> usize; /// Check if this vector is in ascending order according to `T`s `Ord` impl fn zvl_is_ascending(&self) -> bool where
T: Ord,
{ iflet Some(first) = self.zvl_get(0) { letmut prev = first; for i in1..self.zvl_len() { #[allow(clippy::unwrap_used)] // looping over the valid indices let curr = self.zvl_get(i).unwrap(); ifSelf::get_cmp_get(prev, curr) != Ordering::Less { returnfalse;
}
prev = curr;
}
} true
} /// Check if this vector is empty fn zvl_is_empty(&self) -> bool { self.zvl_len() == 0
}
/// Construct a borrowed variant by borrowing from `&self`. /// /// This function behaves like `&'b self -> Self::SliceVariant<'b>`, /// where `'b` is the lifetime of the reference to this object. /// /// Note: We rely on the compiler recognizing `'a` and `'b` as covariant and /// casting `&'b Self<'a>` to `&'b Self<'b>` when this gets called, which works /// out for `ZeroVec` and `VarZeroVec` containers just fine. fn zvl_as_borrowed(&self) -> &Self::SliceVariant;
/// Compare this type with a `Self::GetType`. This must produce the same result as /// if `g` were converted to `Self` #[inline] fn t_cmp_get(t: &T, g: &Self::GetType) -> Ordering where
T: Ord,
{ Self::zvl_get_as_t(g, |g| t.cmp(g))
}
/// Compare two values of `Self::GetType`. This must produce the same result as /// if both `a` and `b` were converted to `Self` #[inline] fn get_cmp_get(a: &Self::GetType, b: &Self::GetType) -> Ordering where
T: Ord,
{ Self::zvl_get_as_t(a, |a| Self::zvl_get_as_t(b, |b| a.cmp(b)))
}
/// Obtain a reference to T, passed to a closure /// /// This uses a callback because it's not possible to return owned-or-borrowed /// types without GATs /// /// Impls should guarantee that the callback function is be called exactly once. fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R;
}
/// Trait abstracting over [`ZeroVec`] and [`VarZeroVec`], for use in [`ZeroMap`](super::ZeroMap). **You /// should not be implementing or calling this trait directly.** /// /// This trait augments [`ZeroVecLike`] with methods allowing for mutation of the underlying /// vector for owned vector types. /// /// Methods are prefixed with `zvl_*` to avoid clashes with methods on the types themselves pubtrait MutableZeroVecLike<'a, T: ?Sized>: ZeroVecLike<T> { /// The type returned by `Self::remove()` and `Self::replace()` type OwnedType;
/// Insert an element at `index` fn zvl_insert(&mutself, index: usize, value: &T); /// Remove the element at `index` (panicking if nonexistant) fn zvl_remove(&mutself, index: usize) -> Self::OwnedType; /// Replace the element at `index` with another one, returning the old element fn zvl_replace(&mutself, index: usize, value: &T) -> Self::OwnedType; /// Push an element to the end of this vector fn zvl_push(&mutself, value: &T); /// Create a new, empty vector, with given capacity fn zvl_with_capacity(cap: usize) -> Self; /// Remove all elements from the vector fn zvl_clear(&mutself); /// Reserve space for `addl` additional elements fn zvl_reserve(&mutself, addl: usize); /// Applies the permutation such that `before.zvl_get(permutation[i]) == after.zvl_get(i)`. /// /// # Panics /// If `permutation` is not a valid permutation of length `zvl_len()`. fn zvl_permute(&mutself, permutation: &mut [usize]);
/// Convert an owned value to a borrowed T fn owned_as_t(o: &Self::OwnedType) -> &T;
/// Construct from the borrowed version of the type /// /// These are useful to ensure serialization parity between borrowed and owned versions fn zvl_from_borrowed(b: &'a Self::SliceVariant) -> Self; /// Extract the inner borrowed variant if possible. Returns `None` if the data is owned. /// /// This function behaves like `&'_ self -> Self::SliceVariant<'a>`, /// where `'a` is the lifetime of this object's borrowed data. /// /// This function is similar to matching the `Borrowed` variant of `ZeroVec` /// or `VarZeroVec`, returning the inner borrowed type. fn zvl_as_borrowed_inner(&self) -> Option<&'a Self::SliceVariant>;
}
impl<'a, T> ZeroVecLike<T> for ZeroVec<'a, T> where
T: 'a + AsULE + Copy,
{ type GetType = T::ULE; type SliceVariant = ZeroSlice<T>;
for cycle_start in0..permutation.len() { letmut curr = cycle_start; letmut next = permutation[curr];
while next != cycle_start {
vec.swap(curr, next); // Make curr a self-cycle so we don't use it as a cycle_start later
permutation[curr] = curr;
curr = next;
next = permutation[next];
}
permutation[curr] = curr;
}
}
}
impl<'a, T, F> ZeroVecLike<T> for VarZeroVec<'a, T, F> where
T: VarULE,
T: ?Sized,
F: VarZeroVecFormat,
{ type GetType = T; type SliceVariant = VarZeroSlice<T, F>;
impl<'a> MutableZeroVecLike<'a, usize> for FlexZeroVec<'a> { type OwnedType = usize; fn zvl_insert(&mutself, index: usize, value: &usize) { self.to_mut().insert(index, *value)
} fn zvl_remove(&mutself, index: usize) -> usize { self.to_mut().remove(index)
} fn zvl_replace(&mutself, index: usize, value: &usize) -> usize { // TODO(#2028): Make this a single operation instead of two operations. let mutable = self.to_mut(); let old_value = mutable.remove(index);
mutable.insert(index, *value);
old_value
} fn zvl_push(&mutself, value: &usize) { self.to_mut().push(*value)
} fn zvl_with_capacity(_cap: usize) -> Self { // There is no `FlexZeroVec::with_capacity()` because it is variable-width
FlexZeroVec::Owned(FlexZeroVecOwned::new_empty())
} fn zvl_clear(&mutself) { self.to_mut().clear()
} fn zvl_reserve(&mutself, _addl: usize) { // There is no `FlexZeroVec::reserve()` because it is variable-width
}
fn owned_as_t(o: &Self::OwnedType) -> &usize {
o
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.