use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections;
use std::fmt::{Debug, Error, Formatter};
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter::{FromIterator, FusedIterator, Sum};
use std::ops::{Add, Mul, RangeBounds};
use archery::SharedPointerKind;
use super::map;
use crate::hashset::GenericHashSet;
use crate::shared_ptr::DefaultSharedPtr;
use crate::GenericOrdMap;
#[macro_export]
macro_rules! ordset {
() => { $crate::ordset::OrdSet::new() };
( $($x:expr),* ) => {{
let mut l = $crate::ordset::OrdSet::new();
$(
l.insert($x);
)*
l
}};
}
pub type OrdSet<A> = GenericOrdSet<A, DefaultSharedPtr>;
pub struct GenericOrdSet<A, P: SharedPointerKind> {
map: GenericOrdMap<A, (), P>,
}
impl<A, P: SharedPointerKind> GenericOrdSet<A, P> {
#[inline]
#[must_use]
pub fn new() -> Self {
GenericOrdSet {
map: GenericOrdMap::new(),
}
}
#[inline]
#[must_use]
pub fn unit(a: A) -> Self {
GenericOrdSet {
map: GenericOrdMap::unit(a, ()),
}
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.map.len()
}
pub fn ptr_eq(&self, other: &Self) -> bool {
self.map.ptr_eq(&other.map)
}
pub fn clear(&mut self) {
self.map.clear();
}
}
impl<A, P> GenericOrdSet<A, P>
where
A: Ord,
P: SharedPointerKind,
{
#[must_use]
pub fn get_min(&self) -> Option<&A> {
self.map.get_min().map(|v| &v.0)
}
#[must_use]
pub fn get_max(&self) -> Option<&A> {
self.map.get_max().map(|v| &v.0)
}
#[must_use]
pub fn iter(&self) -> Iter<'_, A, P> {
Iter {
it: self.map.iter(),
}
}
#[must_use]
pub fn range<R, BA>(&self, range: R) -> RangedIter<'_, A, P>
where
R: RangeBounds<BA>,
A: Borrow<BA>,
BA: Ord + ?Sized,
{
RangedIter {
it: self.map.range(range),
}
}
#[must_use]
pub fn diff<'a, 'b>(&'a self, other: &'b Self) -> DiffIter<'a, 'b, A, P> {
DiffIter {
it: self.map.diff(&other.map),
}
}
#[inline]
#[must_use]
pub fn contains<BA>(&self, a: &BA) -> bool
where
BA: Ord + ?Sized,
A: Borrow<BA>,
{
self.map.contains_key(a)
}
pub fn get<BK>(&self, k: &BK) -> Option<&A>
where
BK: Ord + ?Sized,
A: Borrow<BK>,
{
self.map.get_key_value(k).map(|(k, _)| k)
}
#[must_use]
pub fn get_prev<BK>(&self, k: &BK) -> Option<&A>
where
BK: Ord + ?Sized,
A: Borrow<BK>,
{
self.map.get_prev(k).map(|(k, _)| k)
}
#[must_use]
pub fn get_next<BK>(&self, k: &BK) -> Option<&A>
where
BK: Ord + ?Sized,
A: Borrow<BK>,
{
self.map.get_next(k).map(|(k, _)| k)
}
#[must_use]
pub fn is_subset<RS>(&self, other: RS) -> bool
where
RS: Borrow<Self>,
{
let other = other.borrow();
if other.len() < self.len() {
return false;
}
self.iter().all(|a| other.contains(a))
}
#[must_use]
pub fn is_proper_subset<RS>(&self, other: RS) -> bool
where
RS: Borrow<Self>,
{
self.len() != other.borrow().len() && self.is_subset(other)
}
#[cfg(any(test, fuzzing))]
#[allow(unreachable_pub)]
pub fn check_sane(&self)
where
A: std::fmt::Debug,
{
self.map.check_sane();
}
}
impl<A, P> GenericOrdSet<A, P>
where
A: Ord + Clone,
P: SharedPointerKind,
{
#[inline]
pub fn insert(&mut self, a: A) -> Option<A> {
self.map.insert_key_value(a, ()).map(|(k, _)| k)
}
#[inline]
pub fn remove<BA>(&mut self, a: &BA) -> Option<A>
where
BA: Ord + ?Sized,
A: Borrow<BA>,
{
self.map.remove_with_key(a).map(|(k, _)| k)
}
pub fn remove_min(&mut self) -> Option<A> {
let key = self.get_min()?.clone();
self.remove(&key)
}
pub fn remove_max(&mut self) -> Option<A> {
let key = self.get_max()?.clone();
self.remove(&key)
}
#[must_use]
pub fn update(&self, a: A) -> Self {
let mut out = self.clone();
out.insert(a);
out
}
#[must_use]
pub fn without<BA>(&self, a: &BA) -> Self
where
BA: Ord + ?Sized,
A: Borrow<BA>,
{
let mut out = self.clone();
out.remove(a);
out
}
#[must_use]
pub fn without_min(&self) -> (Option<A>, Self) {
match self.get_min() {
Some(v) => (Some(v.clone()), self.without(v)),
None => (None, self.clone()),
}
}
#[must_use]
pub fn without_max(&self) -> (Option<A>, Self) {
match self.get_max() {
Some(v) => (Some(v.clone()), self.without(v)),
None => (None, self.clone()),
}
}
#[must_use]
pub fn union(self, other: Self) -> Self {
let (mut to_mutate, to_consume) = if self.len() >= other.len() {
(self, other)
} else {
(other, self)
};
for value in to_consume {
to_mutate.insert(value);
}
to_mutate
}
#[must_use]
pub fn unions<I>(i: I) -> Self
where
I: IntoIterator<Item = Self>,
{
i.into_iter().fold(Self::default(), Self::union)
}
#[deprecated(
since = "2.0.1",
note = "to avoid conflicting behaviors between std and imbl, the `difference` alias for `symmetric_difference` will be removed."
)]
#[must_use]
pub fn difference(self, other: Self) -> Self {
self.symmetric_difference(other)
}
#[must_use]
pub fn symmetric_difference(mut self, other: Self) -> Self {
for value in other {
if self.remove(&value).is_none() {
self.insert(value);
}
}
self
}
#[must_use]
pub fn relative_complement(mut self, other: Self) -> Self {
for value in other {
let _ = self.remove(&value);
}
self
}
#[must_use]
pub fn intersection(self, other: Self) -> Self {
let mut out = Self::default();
for value in other {
if self.contains(&value) {
out.insert(value);
}
}
out
}
#[must_use]
pub fn split<BA>(self, split: &BA) -> (Self, Self)
where
BA: Ord + ?Sized,
A: Borrow<BA>,
{
let (left, _, right) = self.split_member(split);
(left, right)
}
#[must_use]
pub fn split_member<BA>(self, split: &BA) -> (Self, bool, Self)
where
BA: Ord + ?Sized,
A: Borrow<BA>,
{
let mut left = Self::default();
let mut right = Self::default();
let mut present = false;
for value in self {
match value.borrow().cmp(split) {
Ordering::Less => {
left.insert(value);
}
Ordering::Equal => {
present = true;
}
Ordering::Greater => {
right.insert(value);
}
}
}
(left, present, right)
}
#[must_use]
pub fn take(&self, n: usize) -> Self {
self.iter().take(n).cloned().collect()
}
#[must_use]
pub fn skip(&self, n: usize) -> Self {
self.iter().skip(n).cloned().collect()
}
}
impl<A, P: SharedPointerKind> Clone for GenericOrdSet<A, P> {
#[inline]
fn clone(&self) -> Self {
GenericOrdSet {
map: self.map.clone(),
}
}
}
impl<A: Ord, P: SharedPointerKind> PartialEq for GenericOrdSet<A, P> {
fn eq(&self, other: &Self) -> bool {
self.map.eq(&other.map)
}
}
impl<A: Ord, P: SharedPointerKind> Eq for GenericOrdSet<A, P> {}
impl<A: Ord, P: SharedPointerKind> PartialOrd for GenericOrdSet<A, P> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<A: Ord, P: SharedPointerKind> Ord for GenericOrdSet<A, P> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl<A: Ord + Hash, P: SharedPointerKind> Hash for GenericOrdSet<A, P> {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
for i in self.iter() {
i.hash(state);
}
}
}
impl<A, P: SharedPointerKind> Default for GenericOrdSet<A, P> {
fn default() -> Self {
GenericOrdSet::new()
}
}
impl<A: Ord + Clone, P: SharedPointerKind> Add for GenericOrdSet<A, P> {
type Output = GenericOrdSet<A, P>;
fn add(self, other: Self) -> Self::Output {
self.union(other)
}
}
impl<A: Ord + Clone, P: SharedPointerKind> Add for &GenericOrdSet<A, P> {
type Output = GenericOrdSet<A, P>;
fn add(self, other: Self) -> Self::Output {
self.clone().union(other.clone())
}
}
impl<A: Ord + Clone, P: SharedPointerKind> Mul for GenericOrdSet<A, P> {
type Output = GenericOrdSet<A, P>;
fn mul(self, other: Self) -> Self::Output {
self.intersection(other)
}
}
impl<A: Ord + Clone, P: SharedPointerKind> Mul for &GenericOrdSet<A, P> {
type Output = GenericOrdSet<A, P>;
fn mul(self, other: Self) -> Self::Output {
self.clone().intersection(other.clone())
}
}
impl<A: Ord + Clone, P: SharedPointerKind> Sum for GenericOrdSet<A, P> {
fn sum<I>(it: I) -> Self
where
I: Iterator<Item = Self>,
{
it.fold(Self::new(), |a, b| a + b)
}
}
impl<A, R, P> Extend<R> for GenericOrdSet<A, P>
where
A: Ord + Clone + From<R>,
P: SharedPointerKind,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = R>,
{
for value in iter {
self.insert(From::from(value));
}
}
}
impl<A: Ord + Debug, P: SharedPointerKind> Debug for GenericOrdSet<A, P> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
f.debug_set().entries(self.iter()).finish()
}
}
pub struct Iter<'a, A, P: SharedPointerKind> {
it: map::Iter<'a, A, (), P>,
}
impl<'a, A, P: SharedPointerKind> Clone for Iter<'a, A, P> {
fn clone(&self) -> Self {
Iter {
it: self.it.clone(),
}
}
}
impl<'a, A, P: SharedPointerKind> Iterator for Iter<'a, A, P>
where
A: 'a + Ord,
{
type Item = &'a A;
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<'a, A, P> DoubleEndedIterator for Iter<'a, A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.it.next_back().map(|(k, _)| k)
}
}
impl<'a, A, P> ExactSizeIterator for Iter<'a, A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
}
impl<'a, A, P> FusedIterator for Iter<'a, A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
}
pub struct RangedIter<'a, A, P: SharedPointerKind> {
it: map::RangedIter<'a, A, (), P>,
}
impl<'a, A, P> Iterator for RangedIter<'a, A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
type Item = &'a A;
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<'a, A, P> DoubleEndedIterator for RangedIter<'a, A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.it.next_back().map(|(k, _)| k)
}
}
pub struct ConsumingIter<A, P: SharedPointerKind> {
it: map::ConsumingIter<A, (), P>,
}
impl<A, P> Iterator for ConsumingIter<A, P>
where
A: Clone,
P: SharedPointerKind,
{
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|v| v.0)
}
}
impl<A, P> DoubleEndedIterator for ConsumingIter<A, P>
where
A: Clone,
P: SharedPointerKind,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.it.next_back().map(|v| v.0)
}
}
impl<A, P> ExactSizeIterator for ConsumingIter<A, P>
where
A: Clone,
P: SharedPointerKind,
{
}
impl<A, P> FusedIterator for ConsumingIter<A, P>
where
A: Clone,
P: SharedPointerKind,
{
}
pub struct DiffIter<'a, 'b, A, P: SharedPointerKind> {
it: map::DiffIter<'a, 'b, A, (), P>,
}
#[derive(PartialEq, Eq, Debug)]
pub enum DiffItem<'a, 'b, A> {
Add(&'b A),
Remove(&'a A),
}
impl<'a, 'b, A, P> Iterator for DiffIter<'a, 'b, A, P>
where
A: Ord + PartialEq,
P: SharedPointerKind,
{
type Item = DiffItem<'a, 'b, A>;
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|item| match item {
map::DiffItem::Add(k, _) => DiffItem::Add(k),
map::DiffItem::Remove(k, _) => DiffItem::Remove(k),
map::DiffItem::Update { .. } => unreachable!(),
})
}
}
impl<'a, 'b, A, P> FusedIterator for DiffIter<'a, 'b, A, P>
where
A: Ord + PartialEq,
P: SharedPointerKind,
{
}
impl<A, R, P> FromIterator<R> for GenericOrdSet<A, P>
where
A: Ord + Clone + From<R>,
P: SharedPointerKind,
{
fn from_iter<T>(i: T) -> Self
where
T: IntoIterator<Item = R>,
{
let mut out = Self::new();
for item in i {
out.insert(From::from(item));
}
out
}
}
impl<'a, A, P> IntoIterator for &'a GenericOrdSet<A, P>
where
A: 'a + Ord,
P: SharedPointerKind,
{
type Item = &'a A;
type IntoIter = Iter<'a, A, P>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<A, P> IntoIterator for GenericOrdSet<A, P>
where
A: Ord + Clone,
P: SharedPointerKind,
{
type Item = A;
type IntoIter = ConsumingIter<A, P>;
fn into_iter(self) -> Self::IntoIter {
ConsumingIter {
it: self.map.into_iter(),
}
}
}
impl<A, OA, P1, P2> From<&GenericOrdSet<&A, P2>> for GenericOrdSet<OA, P1>
where
A: ToOwned<Owned = OA> + Ord + ?Sized,
OA: Borrow<A> + Ord + Clone,
P1: SharedPointerKind,
P2: SharedPointerKind,
{
fn from(set: &GenericOrdSet<&A, P2>) -> Self {
set.iter().map(|a| (*a).to_owned()).collect()
}
}
impl<'a, A, P> From<&'a [A]> for GenericOrdSet<A, P>
where
A: Ord + Clone,
P: SharedPointerKind,
{
fn from(slice: &'a [A]) -> Self {
slice.iter().cloned().collect()
}
}
impl<A: Ord + Clone, P: SharedPointerKind> From<Vec<A>> for GenericOrdSet<A, P> {
fn from(vec: Vec<A>) -> Self {
vec.into_iter().collect()
}
}
impl<A: Ord + Clone, P: SharedPointerKind> From<&Vec<A>> for GenericOrdSet<A, P> {
fn from(vec: &Vec<A>) -> Self {
vec.iter().cloned().collect()
}
}
impl<A: Eq + Hash + Ord + Clone, P: SharedPointerKind> From<collections::HashSet<A>>
for GenericOrdSet<A, P>
{
fn from(hash_set: collections::HashSet<A>) -> Self {
hash_set.into_iter().collect()
}
}
impl<A: Eq + Hash + Ord + Clone, P: SharedPointerKind> From<&collections::HashSet<A>>
for GenericOrdSet<A, P>
{
fn from(hash_set: &collections::HashSet<A>) -> Self {
hash_set.iter().cloned().collect()
}
}
impl<A: Ord + Clone, P: SharedPointerKind> From<collections::BTreeSet<A>> for GenericOrdSet<A, P> {
fn from(btree_set: collections::BTreeSet<A>) -> Self {
btree_set.into_iter().collect()
}
}
impl<A: Ord + Clone, P: SharedPointerKind> From<&collections::BTreeSet<A>> for GenericOrdSet<A, P> {
fn from(btree_set: &collections::BTreeSet<A>) -> Self {
btree_set.iter().cloned().collect()
}
}
impl<A: Hash + Eq + Ord + Clone, S: BuildHasher, P1: SharedPointerKind, P2: SharedPointerKind>
From<GenericHashSet<A, S, P2>> for GenericOrdSet<A, P1>
{
fn from(hashset: GenericHashSet<A, S, P2>) -> Self {
hashset.into_iter().collect()
}
}
impl<A: Hash + Eq + Ord + Clone, S: BuildHasher, P1: SharedPointerKind, P2: SharedPointerKind>
From<&GenericHashSet<A, S, P2>> for GenericOrdSet<A, P1>
{
fn from(hashset: &GenericHashSet<A, S, P2>) -> Self {
hashset.into_iter().cloned().collect()
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::proptest::*;
use proptest::proptest;
use static_assertions::{assert_impl_all, assert_not_impl_any};
assert_impl_all!(OrdSet<i32>: Send, Sync);
assert_not_impl_any!(OrdSet<*const i32>: Send, Sync);
assert_covariant!(OrdSet<T> in T);
#[test]
fn match_strings_with_string_slices() {
let mut set: OrdSet<String> = From::from(&ordset!["foo", "bar"]);
set = set.without("bar");
assert!(!set.contains("bar"));
set.remove("foo");
assert!(!set.contains("foo"));
}
#[test]
fn ranged_iter() {
let set = ordset![1, 2, 3, 4, 5];
let range: Vec<i32> = set.range(..).cloned().collect();
assert_eq!(vec![1, 2, 3, 4, 5], range);
let range: Vec<i32> = set.range(..).rev().cloned().collect();
assert_eq!(vec![5, 4, 3, 2, 1], range);
let range: Vec<i32> = set.range(2..5).cloned().collect();
assert_eq!(vec![2, 3, 4], range);
let range: Vec<i32> = set.range(2..5).rev().cloned().collect();
assert_eq!(vec![4, 3, 2], range);
let range: Vec<i32> = set.range(3..).cloned().collect();
assert_eq!(vec![3, 4, 5], range);
let range: Vec<i32> = set.range(3..).rev().cloned().collect();
assert_eq!(vec![5, 4, 3], range);
let range: Vec<i32> = set.range(..4).cloned().collect();
assert_eq!(vec![1, 2, 3], range);
let range: Vec<i32> = set.range(..4).rev().cloned().collect();
assert_eq!(vec![3, 2, 1], range);
let range: Vec<i32> = set.range(..=3).cloned().collect();
assert_eq!(vec![1, 2, 3], range);
let range: Vec<i32> = set.range(..=3).rev().cloned().collect();
assert_eq!(vec![3, 2, 1], range);
}
proptest! {
#[test]
fn proptest_a_set(ref s in ord_set(".*", 10..100)) {
assert!(s.len() < 100);
assert!(s.len() >= 10);
}
#[test]
fn long_ranged_iter(max in 1..1000) {
let range = 0..max;
let expected: Vec<i32> = range.clone().collect();
let set: OrdSet<i32> = OrdSet::from_iter(range.clone());
let result: Vec<i32> = set.range(..).cloned().collect();
assert_eq!(expected, result);
let expected: Vec<i32> = range.clone().rev().collect();
let set: OrdSet<i32> = OrdSet::from_iter(range);
let result: Vec<i32> = set.range(..).rev().cloned().collect();
assert_eq!(expected, result);
}
}
}