pub struct PetitSet<T, const CAP: usize> { /* private fields */ }
Expand description
A set-like data structure with a fixed maximum size
This data structure does not require the Hash
or Ord
traits,
and instead uses linear iteration to find entries.
Iteration order is guaranteed to be stable, and elements are not re-compressed upon removal.
Under the hood, this is a [PetitMap<T, (), CAP>
].
Principally, this data structure should be used for relatively small sets, where iteration performance, stable-order, stack-allocation and uniqueness are more important than insertion or look-up speed. Iteration, insertion and checking whether an element is in the set are O(CAP). Indexing into a particular element is O(1), as is removing an element at a specific index.
The values are stored as Option
s within an array,
so niche optimization can significantly reduce memory footprint.
The maximum size of this type is given by the const-generic type parameter CAP
.
Entries in this structure are guaranteed to be unique.
Implementations
sourceimpl<T, const CAP: usize> PetitSet<T, CAP>
impl<T, const CAP: usize> PetitSet<T, CAP>
sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty PetitSet
.
The capacity is given by the generic parameter CAP
.
sourcepub fn next_filled_index(&self, cursor: usize) -> Option<usize>
pub fn next_filled_index(&self, cursor: usize) -> Option<usize>
Returns the index of the next filled slot, if any
Returns None if the cursor is larger than CAP
sourcepub fn next_empty_index(&self, cursor: usize) -> Option<usize>
pub fn next_empty_index(&self, cursor: usize) -> Option<usize>
Returns the index of the next empty slot, if any
Returns None if the cursor is larger than CAP
sourcepub fn iter(&self) -> impl Iterator<Item = &T>
pub fn iter(&self) -> impl Iterator<Item = &T>
Returns an iterator over the elements of the PetitSet
sourcepub fn get_at(&self, index: usize) -> Option<&T>
pub fn get_at(&self, index: usize) -> Option<&T>
Returns a reference to the provided index of the underlying array
Returns Some(&T)
if the index is in-bounds and has an element
sourcepub fn get_at_mut(&mut self, index: usize) -> Option<&mut T>
pub fn get_at_mut(&mut self, index: usize) -> Option<&mut T>
Returns a mutable reference to the provided index of the underlying array
Returns Some(&mut T)
if the index is in-bounds and has an element
sourcepub fn remove_at(&mut self, index: usize) -> bool
pub fn remove_at(&mut self, index: usize) -> bool
Removes the element at the provided index
Returns true if an element was found
Panics
Panics if the provided index is larger than CAP.
sourcepub fn take_at(&mut self, index: usize) -> Option<T>
pub fn take_at(&mut self, index: usize) -> Option<T>
Removes the element at the provided index
Returns Some(T)
if an element was found at that index, or None
if no element was there.
Panics
Panics if the provided index is larger than CAP.
sourcepub fn swap_at(&mut self, index_a: usize, index_b: usize)
pub fn swap_at(&mut self, index_a: usize, index_b: usize)
Swaps the element in index_a
with the element in index_b
Panics
Panics if either index is greater than CAP.
sourcepub fn insert_unchecked(&mut self, element: T) -> Option<usize>
pub fn insert_unchecked(&mut self, element: T) -> Option<usize>
Inserts an element into the next empty index of the set, without checking for uniqueness
Returns Some(index) if the operation succeeded, or None if it failed.
Warning
This API is very easy to misuse and will completely break your PetitSet
if you do.
Avoid it unless you are guaranteed by construction that no duplicates exist.
sourceimpl<T: Eq, const CAP: usize> PetitSet<T, CAP>
impl<T: Eq, const CAP: usize> PetitSet<T, CAP>
sourcepub fn find(&self, element: &T) -> Option<usize>
pub fn find(&self, element: &T) -> Option<usize>
Returns the index for the provided element, if it exists in the set
sourcepub fn try_insert(
&mut self,
element: T
) -> Result<SuccesfulSetInsertion, CapacityError<T>>
pub fn try_insert(
&mut self,
element: T
) -> Result<SuccesfulSetInsertion, CapacityError<T>>
Attempt to insert a new element to the set in the first available slot.
Inserts the element if able, then returns the Result
of that operation.
This is either a SuccesfulSetInsertion
or a CapacityError
.
sourcepub fn insert(&mut self, element: T) -> SuccesfulSetInsertion
pub fn insert(&mut self, element: T) -> SuccesfulSetInsertion
Insert a new element to the set in the first available slot
Returns a SuccesfulSetInsertion
, which encodes both the index at which the element is stored
and whether the element was already present.
Panics
Panics if the set is full and the item is not a duplicate
sourcepub fn insert_at(&mut self, element: T, index: usize) -> Option<T>
pub fn insert_at(&mut self, element: T, index: usize) -> Option<T>
Insert a new element to the set at the provided index
If a matching element already existed in the set, it will be moved to the supplied index. Any element that was previously there will be moved to the matching element’s original index.
Returns Some(T)
of any element removed by this operation.
Panics
Panics if the provided index is larger than CAP.
sourcepub fn try_extend(
&mut self,
elements: impl IntoIterator<Item = T>
) -> Result<(), CapacityError<T>>
pub fn try_extend(
&mut self,
elements: impl IntoIterator<Item = T>
) -> Result<(), CapacityError<T>>
Inserts multiple new elements to the set. Duplicate elements are discarded.
Returns a CapacityError
if the extension cannot be completed because the set is full.
sourcepub fn remove(&mut self, element: &T) -> Option<usize>
pub fn remove(&mut self, element: &T) -> Option<usize>
Removes the element from the set, if it exists
Returns Some(index)
if the element was found, or None
if no matching element is found
sourcepub fn take(&mut self, element: &T) -> Option<(usize, T)>
pub fn take(&mut self, element: &T) -> Option<(usize, T)>
Removes an element from the set, if it exists, returning both the value that compared equal and the index at which it was stored.
sourcepub fn swap(&mut self, element_a: &T, element_b: &T) -> bool
pub fn swap(&mut self, element_a: &T, element_b: &T) -> bool
Swaps the positions of element_a
with the position of element_b
Returns true if both elements were found and succesfully swapped.
sourcepub fn identical(&self, other: Self) -> bool
pub fn identical(&self, other: Self) -> bool
Are the two PetitSet
s element-for-element identical, in the same order?
sourcepub fn retain<F>(&mut self, f: F) where
F: FnMut(&T) -> bool,
pub fn retain<F>(&mut self, f: F) where
F: FnMut(&T) -> bool,
Retains only the elements specified by the predicate.
In other words, remove all elements e such that f(&e) returns false. The elements are visited in order.
sourcepub fn try_from_iter<I: IntoIterator<Item = T>>(
element_iter: I
) -> Result<Self, CapacityError<(Self, T)>>
pub fn try_from_iter<I: IntoIterator<Item = T>>(
element_iter: I
) -> Result<Self, CapacityError<(Self, T)>>
Constructs a new PetitSet
by consuming values from an iterator.
The consumed values will be stored in order, with duplicate elements discarded.
Returns an error if the iterator produces more than CAP
distinct elements. The
returned error will include both the element that could not be inserted, and
a PetitSet
containing all elements up to that point.
Example
use petitset::CapacityError;
use petitset::PetitSet;
let elems = vec![1, 2, 1, 4, 3, 1];
let set = PetitSet::<_, 5>::try_from_iter(elems.iter().copied());
assert_eq!(set, Ok(PetitSet::from_raw_array_unchecked([Some(1), Some(2), Some(4), Some(3), None])));
let failed = PetitSet::<_, 3>::try_from_iter(elems.iter().copied());
assert_eq!(failed, Err(CapacityError((PetitSet::from_raw_array_unchecked([Some(1), Some(2), Some(4)]), 3))));
sourcepub fn from_raw_array_unchecked(values: [Option<T>; CAP]) -> Self
pub fn from_raw_array_unchecked(values: [Option<T>; CAP]) -> Self
sourceimpl<T: Eq + Clone, const CAP: usize> PetitSet<T, CAP>
impl<T: Eq + Clone, const CAP: usize> PetitSet<T, CAP>
sourcepub fn is_disjoint<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
pub fn is_disjoint<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
Do the sets contain any common elements?
Examples
use petitset::PetitSet;
let set_a: PetitSet<usize, 3> = PetitSet::from_iter([7, 13, 5]);
let set_b: PetitSet<usize, 5> = PetitSet::from_iter([15, 7, 3, 4, 5]);
let mut set_c: PetitSet<usize, 1> = PetitSet::default();
set_c.insert(42);
assert!(!set_a.is_disjoint(&set_b));
assert!(!set_b.is_disjoint(&set_a));
assert!(set_a.is_disjoint(&set_c));
assert!(set_c.is_disjoint(&set_a));
sourcepub fn is_subset<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
pub fn is_subset<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
Are all elements in self
contained in other
?
Examples
use petitset::PetitSet;
let set_a: PetitSet<usize, 3> = PetitSet::from_iter([1, 2, 3]);
let set_b: PetitSet<usize, 5> = PetitSet::from_iter([2, 3]);
assert!(set_a.is_subset(&set_a));
assert!(!set_a.is_subset(&set_b));
assert!(set_b.is_subset(&set_a));
sourcepub fn is_superset<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
pub fn is_superset<const OTHER_CAP: usize>(
&self,
other: &PetitSet<T, OTHER_CAP>
) -> bool
Are all elements in other
contained in self
?
Examples
use petitset::PetitSet;
let set_a: PetitSet<usize, 3> = PetitSet::from_iter([1, 2, 3]);
let set_b: PetitSet<usize, 5> = PetitSet::from_iter([2, 3]);
assert!(set_a.is_superset(&set_a));
assert!(set_a.is_superset(&set_b));
assert!(!set_b.is_superset(&set_a));
Trait Implementations
sourceimpl<T: Eq, const CAP: usize> Extend<T> for PetitSet<T, CAP>
impl<T: Eq, const CAP: usize> Extend<T> for PetitSet<T, CAP>
sourcefn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Inserts multiple new elements to the set. Duplicate elements are discarded.
Panics
Panics if the set would overflow due to the insertion of non-duplicate items
sourcefn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Extends a collection with exactly one element.
sourcefn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
sourceimpl<T: Eq, const CAP: usize> FromIterator<T> for PetitSet<T, CAP>
impl<T: Eq, const CAP: usize> FromIterator<T> for PetitSet<T, CAP>
sourcefn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Panics if the iterator contains more than CAP
distinct elements.
sourceimpl<T: Eq, const CAP: usize> IntoIterator for PetitSet<T, CAP>
impl<T: Eq, const CAP: usize> IntoIterator for PetitSet<T, CAP>
sourceimpl<T: Eq, const CAP: usize, const OTHER_CAP: usize> PartialEq<PetitSet<T, OTHER_CAP>> for PetitSet<T, CAP>
impl<T: Eq, const CAP: usize, const OTHER_CAP: usize> PartialEq<PetitSet<T, OTHER_CAP>> for PetitSet<T, CAP>
impl<T: Eq, const CAP: usize> Eq for PetitSet<T, CAP>
Auto Trait Implementations
impl<T, const CAP: usize> RefUnwindSafe for PetitSet<T, CAP> where
T: RefUnwindSafe,
impl<T, const CAP: usize> Send for PetitSet<T, CAP> where
T: Send,
impl<T, const CAP: usize> Sync for PetitSet<T, CAP> where
T: Sync,
impl<T, const CAP: usize> Unpin for PetitSet<T, CAP> where
T: Unpin,
impl<T, const CAP: usize> UnwindSafe for PetitSet<T, CAP> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more