use core::fmt;
use equivalent::Comparable;
use std::{
cmp::Ordering,
hash::{Hash, Hasher},
iter::FusedIterator,
ops::Index,
};
use crate::{
multi_map::{self, BTreeIndexMultiMap},
util::entries_as_slice,
};
#[derive(Clone)]
pub struct BTreeIndexMultiSet<T> {
map: BTreeIndexMultiMap<T, ()>,
}
impl<T> Default for BTreeIndexMultiSet<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> BTreeIndexMultiSet<T> {
pub fn new() -> Self {
Self {
map: BTreeIndexMultiMap::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: BTreeIndexMultiMap::with_capacity(capacity),
}
}
pub fn singleton(value: T) -> Self
where
T: Ord,
{
Self {
map: BTreeIndexMultiMap::singleton(value, ()),
}
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn as_slice(&self) -> &[T] {
entries_as_slice(self.map.as_entries())
}
pub fn first(&self) -> Option<&T> {
self.map.first().map(|(t, ())| t)
}
pub fn last(&self) -> Option<&T> {
self.map.last().map(|(t, ())| t)
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
Q: ?Sized + Comparable<T>,
{
self.map.contains_key(value)
}
pub fn count<Q>(&self, value: &Q) -> usize
where
Q: ?Sized + Comparable<T>,
{
self.map.key_occurences(value)
}
pub fn indexes_of<Q>(&self, value: &Q) -> multi_map::IndexesIter<'_>
where
Q: ?Sized + Comparable<T>,
{
self.map.indexes_of(value)
}
pub fn index_of<Q>(&self, value: &Q) -> Option<usize>
where
Q: ?Sized + Comparable<T>,
{
self.map.index_of(value)
}
pub fn get_indexed<Q>(&self, value: &Q) -> GetIndexed<'_, T>
where
Q: ?Sized + Comparable<T>,
{
GetIndexed(self.map.get_indexed_entries(value))
}
pub fn get<Q>(&self, value: &Q) -> Get<'_, T>
where
Q: ?Sized + Comparable<T>,
{
Get(self.map.get_indexed_entries(value))
}
pub fn push_back(&mut self, value: T) -> (usize, bool)
where
T: Ord,
{
self.map.push_back(value, ())
}
pub fn push_front(&mut self, value: T) -> bool
where
T: Ord,
{
self.map.push_front(value, ())
}
pub fn insert_at(&mut self, index: usize, value: T) -> bool
where
T: Ord,
{
self.map.insert_at(index, value, ())
}
pub fn insert(&mut self, value: T) -> (usize, bool)
where
T: Ord,
{
self.push_back(value)
}
pub fn shift_remove_at(&mut self, index: usize) -> Option<T>
where
T: Ord,
{
self.map.shift_remove_at(index).map(|(t, ())| t)
}
pub fn swap_remove_at(&mut self, index: usize) -> Option<T>
where
T: Ord,
{
self.map.swap_remove_at(index).map(|(t, ())| t)
}
pub fn shift_remove<Q>(&mut self, value: &Q) -> ShiftRemove<'_, T>
where
Q: ?Sized + Comparable<T>,
{
ShiftRemove(self.map.shift_remove_entries(value))
}
pub fn swap_remove<Q>(&mut self, value: &Q) -> SwapRemove<'_, T>
where
Q: ?Sized + Comparable<T>,
T: Ord,
{
SwapRemove(self.map.swap_remove_entries(value))
}
pub fn iter(&self) -> Iter<'_, T> {
self.as_slice().iter()
}
pub fn iter_sorted(&self) -> IterSorted<'_, T> {
IterSorted(self.map.iter_sorted())
}
pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
IntoIterSorted(self.map.into_iter_sorted())
}
pub fn sort(&mut self)
where
T: Ord,
{
self.map.sort()
}
}
impl<T> Index<usize> for BTreeIndexMultiSet<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.as_slice()[index]
}
}
impl<T> IntoIterator for BTreeIndexMultiSet<T> {
type IntoIter = IntoIter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
IntoIter(self.map.into_iter())
}
}
impl<T: PartialEq> PartialEq for BTreeIndexMultiSet<T> {
fn eq(&self, other: &Self) -> bool {
self.iter_sorted().eq(other.iter_sorted())
}
}
impl<T: Eq> Eq for BTreeIndexMultiSet<T> {}
impl<T: PartialOrd> PartialOrd for BTreeIndexMultiSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter_sorted().partial_cmp(other.iter_sorted())
}
}
impl<T: Ord> Ord for BTreeIndexMultiSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter_sorted().cmp(other.iter_sorted())
}
}
impl<T: Hash> Hash for BTreeIndexMultiSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(self.len());
for item in self.iter_sorted() {
item.hash(state);
}
}
}
impl<T: fmt::Debug> fmt::Debug for BTreeIndexMultiSet<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T: Ord> Extend<T> for BTreeIndexMultiSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for value in iter {
self.push_back(value);
}
}
}
impl<T: Ord> FromIterator<T> for BTreeIndexMultiSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut result = Self::new();
result.extend(iter);
result
}
}
pub struct GetIndexed<'a, T>(multi_map::GetIndexedEntries<'a, T, ()>);
impl<'a, T> Iterator for GetIndexed<'a, T> {
type Item = (usize, &'a T);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(i, t, ())| (i, t))
}
}
pub struct Get<'a, T>(multi_map::GetIndexedEntries<'a, T, ()>);
impl<'a, T> Iterator for Get<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(_, t, ())| t)
}
}
pub struct ShiftRemove<'a, T>(multi_map::ShiftRemoveEntries<'a, T, ()>);
impl<'a, T> Iterator for ShiftRemove<'a, T> {
type Item = T;
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(t, ())| t)
}
}
impl<T> ExactSizeIterator for ShiftRemove<'_, T> {}
pub struct SwapRemove<'a, T: Ord>(multi_map::SwapRemoveEntries<'a, T, ()>);
impl<'a, T: Ord> Iterator for SwapRemove<'a, T> {
type Item = T;
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(t, ())| t)
}
}
impl<T: Ord> ExactSizeIterator for SwapRemove<'_, T> {}
pub type Iter<'a, T> = std::slice::Iter<'a, T>;
impl<'a, T> IntoIterator for &'a BTreeIndexMultiSet<T> {
type IntoIter = Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct IterSorted<'a, T>(multi_map::IterSorted<'a, T, ()>);
impl<'a, T> Iterator for IterSorted<'a, T> {
type Item = &'a T;
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(t, ())| t)
}
}
impl<T> ExactSizeIterator for IterSorted<'_, T> {}
impl<T> FusedIterator for IterSorted<'_, T> {}
pub struct IntoIterSorted<T>(multi_map::IntoIterSorted<T, ()>);
impl<T> Iterator for IntoIterSorted<T> {
type Item = T;
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(t, ())| t)
}
}
impl<T> ExactSizeIterator for IntoIterSorted<T> {}
impl<T> FusedIterator for IntoIterSorted<T> {}
pub struct IntoIter<T>(multi_map::IntoIter<T, ()>);
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(t, ())| t)
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|(t, ())| t)
}
}
impl<T> ExactSizeIterator for IntoIter<T> {}
impl<T> FusedIterator for IntoIter<T> {}