use compare::{Compare, Natural};
use std::cmp::Ordering;
#[cfg(feature = "range")] use std::collections::Bound;
use std::fmt::{self, Debug};
use std::hash::{self, Hash};
use std::iter;
use super::map::{self, Map};
#[derive(Clone)]
pub struct Set<T, C = Natural<T>> where C: Compare<T> {
map: Map<T, (), C>,
}
impl<T> Set<T> where T: Ord {
pub fn new() -> Self { Set { map: Map::new() } }
}
impl<T, C> Set<T, C> where C: Compare<T> {
pub fn with_cmp(cmp: C) -> Self { Set { map: Map::with_cmp(cmp) } }
pub fn is_empty(&self) -> bool { self.map.is_empty() }
pub fn len(&self) -> usize { self.map.len() }
pub fn cmp(&self) -> &C { self.map.cmp() }
pub fn clear(&mut self) { self.map.clear(); }
pub fn insert(&mut self, item: T) -> bool { self.map.insert(item, ()).is_none() }
pub fn remove<Q: ?Sized>(&mut self, item: &Q) -> bool where C: Compare<Q, T> {
self.map.remove(item).is_some()
}
pub fn entry(&mut self, item: T) -> Entry<T> {
match self.map.entry(item) {
map::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry(e)),
map::Entry::Vacant(e) => Entry::Vacant(VacantEntry(e)),
}
}
pub fn contains<Q: ?Sized>(&self, item: &Q) -> bool where C: Compare<Q, T> {
self.map.contains_key(item)
}
pub fn max(&self) -> Option<&T> { self.map.max().map(|e| e.0) }
pub fn remove_max(&mut self) -> Option<T> { self.map.remove_max().map(|e| e.0) }
pub fn max_entry(&mut self) -> Option<OccupiedEntry<T>> {
self.map.max_entry().map(OccupiedEntry)
}
pub fn min(&self) -> Option<&T> { self.map.min().map(|e| e.0) }
pub fn remove_min(&mut self) -> Option<T> { self.map.remove_min().map(|e| e.0) }
pub fn min_entry(&mut self) -> Option<OccupiedEntry<T>> {
self.map.min_entry().map(OccupiedEntry)
}
pub fn pred<Q: ?Sized>(&self, item: &Q, inclusive: bool) -> Option<&T> where C: Compare<Q, T> {
self.map.pred(item, inclusive).map(|e| e.0)
}
pub fn remove_pred<Q: ?Sized>(&mut self, item: &Q, inclusive: bool) -> Option<T>
where C: Compare<Q, T> {
self.map.remove_pred(item, inclusive).map(|e| e.0)
}
pub fn pred_entry<Q: ?Sized>(&mut self, item: &Q, inclusive: bool)
-> Option<OccupiedEntry<T>> where C: Compare<Q, T> {
self.map.pred_entry(item, inclusive).map(OccupiedEntry)
}
pub fn succ<Q: ?Sized>(&self, item: &Q, inclusive: bool) -> Option<&T> where C: Compare<Q, T> {
self.map.succ(item, inclusive).map(|e| e.0)
}
pub fn remove_succ<Q: ?Sized>(&mut self, item: &Q, inclusive: bool) -> Option<T>
where C: Compare<Q, T> {
self.map.remove_succ(item, inclusive).map(|e| e.0)
}
pub fn succ_entry<Q: ?Sized>(&mut self, item: &Q, inclusive: bool)
-> Option<OccupiedEntry<T>> where C: Compare<Q, T> {
self.map.succ_entry(item, inclusive).map(OccupiedEntry)
}
pub fn iter(&self) -> Iter<T> { Iter(self.map.iter()) }
}
#[cfg(feature = "range")]
impl<T, C> Set<T, C> where C: Compare<T> {
pub fn into_range<Min: ?Sized, Max: ?Sized>(self, min: Bound<&Min>, max: Bound<&Max>)
-> IntoRange<T> where C: Compare<Min, T> + Compare<Max, T> {
IntoRange(self.map.into_range(min, max))
}
pub fn range<Min: ?Sized, Max: ?Sized>(&self, min: Bound<&Min>, max: Bound<&Max>)
-> Range<T> where C: Compare<Min, T> + Compare<Max, T> {
Range(self.map.range(min, max))
}
}
impl<T, C> Debug for Set<T, C> where T: Debug, C: Compare<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_set().entries(self).finish()
}
}
impl<T, C> Default for Set<T, C> where C: Compare<T> + Default {
fn default() -> Self { Set::with_cmp(C::default()) }
}
impl<T, C> Extend<T> for Set<T, C> where C: Compare<T> {
fn extend<I: IntoIterator<Item=T>>(&mut self, it: I) {
for item in it { self.insert(item); }
}
}
impl<T, C> iter::FromIterator<T> for Set<T, C> where C: Compare<T> + Default {
fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Self {
let mut set = Set::default();
set.extend(it);
set
}
}
impl<T, C> Hash for Set<T, C> where T: Hash, C: Compare<T> {
fn hash<H: hash::Hasher>(&self, h: &mut H) { self.map.hash(h); }
}
impl<'a, T, C> IntoIterator for &'a Set<T, C> where C: Compare<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { self.iter() }
}
impl<T, C> IntoIterator for Set<T, C> where C: Compare<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> { IntoIter(self.map.into_iter()) }
}
impl<T, C> PartialEq for Set<T, C> where C: Compare<T> {
fn eq(&self, other: &Self) -> bool { self.map == other.map }
}
impl<T, C> Eq for Set<T, C> where C: Compare<T> {}
impl<T, C> PartialOrd for Set<T, C> where C: Compare<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T, C> Ord for Set<T, C> where C: Compare<T> {
fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(&self.map, &other.map) }
}
#[derive(Clone)]
pub struct IntoIter<T>(map::IntoIter<T, ()>);
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> { self.0.next().map(|e| e.0) }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn count(self) -> usize { self.0.count() }
fn last(self) -> Option<Self::Item> { self.0.last().map(|e| e.0) }
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back().map(|e| e.0) }
}
impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize { self.0.len() }
}
pub struct Iter<'a, T: 'a>(map::Iter<'a, T, ()>);
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Self { Iter(self.0.clone()) }
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { self.0.next().map(|e| e.0) }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn count(self) -> usize { self.0.count() }
fn last(self) -> Option<Self::Item> { self.0.last().map(|e| e.0) }
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back().map(|e| e.0) }
}
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize { self.0.len() }
}
#[cfg(feature = "range")]
#[derive(Clone)]
pub struct IntoRange<T>(map::IntoRange<T, ()>);
#[cfg(feature = "range")]
impl<T> Iterator for IntoRange<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> { self.0.next().map(|e| e.0) }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn last(self) -> Option<Self::Item> { self.0.last().map(|e| e.0) }
}
#[cfg(feature = "range")]
impl<T> DoubleEndedIterator for IntoRange<T> {
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back().map(|e| e.0) }
}
#[cfg(feature = "range")]
pub struct Range<'a, T: 'a>(map::Range<'a, T, ()>);
#[cfg(feature = "range")]
impl<'a, T> Clone for Range<'a, T> {
fn clone(&self) -> Self { Range(self.0.clone()) }
}
#[cfg(feature = "range")]
impl<'a, T> Iterator for Range<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { self.0.next().map(|e| e.0) }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn last(self) -> Option<Self::Item> { self.0.last().map(|e| e.0) }
}
#[cfg(feature = "range")]
impl<'a, T> DoubleEndedIterator for Range<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back().map(|e| e.0) }
}
pub enum Entry<'a, T: 'a> {
Occupied(OccupiedEntry<'a, T>),
Vacant(VacantEntry<'a, T>),
}
pub struct OccupiedEntry<'a, T: 'a>(map::OccupiedEntry<'a, T, ()>);
impl<'a, T> OccupiedEntry<'a, T> {
pub fn get(&self) -> &T { self.0.key() }
pub fn remove(self) -> T { self.0.remove().0 }
}
pub struct VacantEntry<'a, T: 'a>(map::VacantEntry<'a, T, ()>);
impl<'a, T> VacantEntry<'a, T> {
pub fn insert(self) { self.0.insert(()); }
}