use std::borrow::Borrow;
use std::fmt;
use std::iter::{Chain, FromIterator};
use std::ops::{BitOr, BitAnd, BitXor, Sub};
use super::{LinearMap, Keys};
#[derive(Clone)]
pub struct LinearSet<T> {
map: LinearMap<T, ()>
}
impl<T: Eq> LinearSet<T> {
#[inline]
pub fn new() -> LinearSet<T> {
LinearSet { map: LinearMap::new() }
}
#[inline]
pub fn with_capacity(capacity: usize) -> LinearSet<T> {
LinearSet { map: LinearMap::with_capacity(capacity) }
}
}
impl<T> LinearSet<T>
where T: Eq
{
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional)
}
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit()
}
pub fn iter(&self) -> Iter<T> {
Iter { iter: self.map.keys() }
}
pub fn difference<'a>(&'a self, other: &'a LinearSet<T>) -> Difference<'a, T> {
Difference {
iter: self.iter(),
other: other,
}
}
pub fn symmetric_difference<'a>(&'a self, other: &'a LinearSet<T>)
-> SymmetricDifference<'a, T> {
SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
}
pub fn intersection<'a>(&'a self, other: &'a LinearSet<T>) -> Intersection<'a, T> {
Intersection {
iter: self.iter(),
other: other,
}
}
pub fn union<'a>(&'a self, other: &'a LinearSet<T>) -> Union<'a, T> {
Union { iter: self.iter().chain(other.difference(self)) }
}
pub fn len(&self) -> usize { self.map.len() }
pub fn is_empty(&self) -> bool { self.map.is_empty() }
#[inline]
pub fn drain(&mut self) -> Drain<T> {
Drain { iter: self.map.drain() }
}
pub fn clear(&mut self) { self.map.clear() }
pub fn retain<F>(&mut self, mut f: F)
where F: FnMut(&T) -> bool {
self.map.retain(|k, _| f(k));
}
pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
where T: Borrow<Q>, Q: Eq
{
self.map.contains_key(value)
}
pub fn is_disjoint(&self, other: &LinearSet<T>) -> bool {
self.iter().all(|v| !other.contains(v))
}
pub fn is_subset(&self, other: &LinearSet<T>) -> bool {
self.iter().all(|v| other.contains(v))
}
#[inline]
pub fn is_superset(&self, other: &LinearSet<T>) -> bool {
other.is_subset(self)
}
pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
where T: Borrow<Q>, Q: Eq
{
self.map.remove(value).is_some()
}
}
impl<T> PartialEq for LinearSet<T>
where T: Eq
{
fn eq(&self, other: &LinearSet<T>) -> bool {
if self.len() != other.len() { return false; }
self.iter().all(|key| other.contains(key))
}
}
impl<T> Eq for LinearSet<T>
where T: Eq
{}
impl<T> fmt::Debug for LinearSet<T>
where T: Eq + fmt::Debug
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> FromIterator<T> for LinearSet<T>
where T: Eq
{
fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> LinearSet<T> {
let iterator = iter.into_iter();
let lower = iterator.size_hint().0;
let mut set = LinearSet::with_capacity(lower);
set.extend(iterator);
set
}
}
impl<T> Extend<T> for LinearSet<T>
where T: Eq
{
fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
for k in iter {
self.insert(k);
}
}
}
impl<'a, T> Extend<&'a T> for LinearSet<T>
where T: 'a + Eq + Copy
{
fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
}
}
impl<T> Default for LinearSet<T>
where T: Eq
{
fn default() -> LinearSet<T> {
LinearSet::new()
}
}
impl<K: Eq> Into<Vec<K>> for LinearSet<K> {
fn into(self) -> Vec<K> {
unsafe {
use std::mem;
mem::transmute(self)
}
}
}
impl<'a, 'b, T> BitOr<&'b LinearSet<T>> for &'a LinearSet<T>
where T: Eq + Clone
{
type Output = LinearSet<T>;
fn bitor(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.union(rhs).cloned().collect()
}
}
impl<'a, 'b, T> BitAnd<&'b LinearSet<T>> for &'a LinearSet<T>
where T: Eq + Clone
{
type Output = LinearSet<T>;
fn bitand(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.intersection(rhs).cloned().collect()
}
}
impl<'a, 'b, T> BitXor<&'b LinearSet<T>> for &'a LinearSet<T>
where T: Eq + Clone
{
type Output = LinearSet<T>;
fn bitxor(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.symmetric_difference(rhs).cloned().collect()
}
}
impl<'a, 'b, T> Sub<&'b LinearSet<T>> for &'a LinearSet<T>
where T: Eq + Clone
{
type Output = LinearSet<T>;
fn sub(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.difference(rhs).cloned().collect()
}
}
pub struct Iter<'a, K: 'a> {
iter: Keys<'a, K, ()>
}
pub struct IntoIter<K> {
iter: super::IntoIter<K, ()>
}
pub struct Drain<'a, K: 'a> {
iter: super::Drain<'a, K, ()>,
}
pub struct Intersection<'a, T: 'a> {
iter: Iter<'a, T>,
other: &'a LinearSet<T>,
}
pub struct Difference<'a, T: 'a> {
iter: Iter<'a, T>,
other: &'a LinearSet<T>,
}
pub struct SymmetricDifference<'a, T: 'a> {
iter: Chain<Difference<'a, T>, Difference<'a, T>>
}
pub struct Union<'a, T: 'a> {
iter: Chain<Iter<'a, T>, Difference<'a, T>>
}
impl<'a, T> IntoIterator for &'a LinearSet<T>
where T: Eq
{
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<T> IntoIterator for LinearSet<T>
where T: Eq
{
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter { iter: self.map.into_iter() }
}
}
impl<'a, K> Clone for Iter<'a, K> {
fn clone(&self) -> Iter<'a, K> { Iter { iter: self.iter.clone() } }
}
impl<'a, K> Iterator for Iter<'a, K> {
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<'a, K> ExactSizeIterator for Iter<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
impl<K> Iterator for IntoIter<K> {
type Item = K;
fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<K> ExactSizeIterator for IntoIter<K> {
fn len(&self) -> usize { self.iter.len() }
}
impl<'a, K> Iterator for Drain<'a, K> {
type Item = K;
fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<'a, K> ExactSizeIterator for Drain<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
impl<'a, T> Clone for Intersection<'a, T> {
fn clone(&self) -> Intersection<'a, T> {
Intersection { iter: self.iter.clone(), ..*self }
}
}
impl<'a, T> Iterator for Intersection<'a, T>
where T: Eq
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match self.iter.next() {
None => return None,
Some(elt) => if self.other.contains(elt) {
return Some(elt)
},
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<'a, T> Clone for Difference<'a, T> {
fn clone(&self) -> Difference<'a, T> {
Difference { iter: self.iter.clone(), ..*self }
}
}
impl<'a, T> Iterator for Difference<'a, T>
where T: Eq
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match self.iter.next() {
None => return None,
Some(elt) => if !self.other.contains(elt) {
return Some(elt)
},
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<'a, T> Clone for SymmetricDifference<'a, T> {
fn clone(&self) -> SymmetricDifference<'a, T> {
SymmetricDifference { iter: self.iter.clone() }
}
}
impl<'a, T> Iterator for SymmetricDifference<'a, T>
where T: Eq
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<'a, T> Clone for Union<'a, T> {
fn clone(&self) -> Union<'a, T> { Union { iter: self.iter.clone() } }
}
impl<'a, T> Iterator for Union<'a, T>
where T: Eq
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[allow(dead_code)]
fn assert_covariance() {
fn set<'new>(v: LinearSet<&'static str>) -> LinearSet<&'new str> { v }
fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { v }
fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v }
fn difference<'a, 'new>(v: Difference<'a, &'static str>)
-> Difference<'a, &'new str> { v }
fn symmetric_difference<'a, 'new>(v: SymmetricDifference<'a, &'static str>)
-> SymmetricDifference<'a, &'new str> { v }
fn intersection<'a, 'new>(v: Intersection<'a, &'static str>)
-> Intersection<'a, &'new str> { v }
fn union<'a, 'new>(v: Union<'a, &'static str>)
-> Union<'a, &'new str> { v }
}