Kill unique and shared

This commit is contained in:
Manish Goregaokar 2017-08-25 16:22:11 -07:00
parent 17bcb443cb
commit 2b99611291
4 changed files with 99 additions and 35 deletions

View file

@ -1035,7 +1035,7 @@ impl<K, V, S> HashMap<K, V, S>
/// assert!(a.is_empty()); /// assert!(a.is_empty());
/// ``` /// ```
#[inline] #[inline]
pub fn drain(&mut self) -> Drain<K, V> { pub fn drain(&mut self) -> Drain<K, V> where K: 'static, V: 'static {
Drain { inner: self.table.drain() } Drain { inner: self.table.drain() }
} }
@ -1053,7 +1053,7 @@ impl<K, V, S> HashMap<K, V, S>
/// assert!(a.is_empty()); /// assert!(a.is_empty());
/// ``` /// ```
#[inline] #[inline]
pub fn clear(&mut self) { pub fn clear(&mut self) where K: 'static, V: 'static {
self.drain(); self.drain();
} }
@ -1409,7 +1409,7 @@ impl<'a, K, V: Debug> fmt::Debug for Values<'a, K, V> {
/// ///
/// [`drain`]: struct.HashMap.html#method.drain /// [`drain`]: struct.HashMap.html#method.drain
/// [`HashMap`]: struct.HashMap.html /// [`HashMap`]: struct.HashMap.html
pub struct Drain<'a, K: 'a, V: 'a> { pub struct Drain<'a, K: 'static, V: 'static> {
pub(super) inner: table::Drain<'a, K, V>, pub(super) inner: table::Drain<'a, K, V>,
} }

View file

@ -131,7 +131,7 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
/// let set: HashSet<i32> = HashSet::new(); /// let set: HashSet<i32> = HashSet::new();
/// ``` /// ```
#[inline] #[inline]
pub fn new() -> HashSet<T, RandomState> { pub fn new() -> HashSet<T, RandomState> {
HashSet { map: HashMap::new() } HashSet { map: HashMap::new() }
} }
@ -148,7 +148,7 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
/// assert!(set.capacity() >= 10); /// assert!(set.capacity() >= 10);
/// ``` /// ```
#[inline] #[inline]
pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> { pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
HashSet { map: HashMap::with_capacity(capacity) } HashSet { map: HashMap::with_capacity(capacity) }
} }
} }
@ -178,7 +178,7 @@ impl<T, S> HashSet<T, S>
/// set.insert(2); /// set.insert(2);
/// ``` /// ```
#[inline] #[inline]
pub fn with_hasher(hasher: S) -> HashSet<T, S> { pub fn with_hasher(hasher: S) -> HashSet<T, S> {
HashSet { map: HashMap::with_hasher(hasher) } HashSet { map: HashMap::with_hasher(hasher) }
} }
@ -204,7 +204,7 @@ impl<T, S> HashSet<T, S>
/// set.insert(1); /// set.insert(1);
/// ``` /// ```
#[inline] #[inline]
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> { pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) } HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
} }
@ -222,7 +222,7 @@ impl<T, S> HashSet<T, S>
/// let set: HashSet<i32> = HashSet::with_hasher(hasher); /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
/// let hasher: &RandomState = set.hasher(); /// let hasher: &RandomState = set.hasher();
/// ``` /// ```
pub fn hasher(&self) -> &S { pub fn hasher(&self) -> &S {
self.map.hasher() self.map.hasher()
} }
@ -236,7 +236,7 @@ impl<T, S> HashSet<T, S>
/// assert!(set.capacity() >= 100); /// assert!(set.capacity() >= 100);
/// ``` /// ```
#[inline] #[inline]
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
self.map.capacity() self.map.capacity()
} }
@ -256,7 +256,7 @@ impl<T, S> HashSet<T, S>
/// set.reserve(10); /// set.reserve(10);
/// assert!(set.capacity() >= 10); /// assert!(set.capacity() >= 10);
/// ``` /// ```
pub fn reserve(&mut self, additional: usize) { pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional) self.map.reserve(additional)
} }
@ -276,7 +276,7 @@ impl<T, S> HashSet<T, S>
/// set.shrink_to_fit(); /// set.shrink_to_fit();
/// assert!(set.capacity() >= 2); /// assert!(set.capacity() >= 2);
/// ``` /// ```
pub fn shrink_to_fit(&mut self) { pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit() self.map.shrink_to_fit()
} }
@ -296,7 +296,7 @@ impl<T, S> HashSet<T, S>
/// println!("{}", x); /// println!("{}", x);
/// } /// }
/// ``` /// ```
pub fn iter(&self) -> Iter<T> { pub fn iter(&self) -> Iter<T> {
Iter { iter: self.map.keys() } Iter { iter: self.map.keys() }
} }
@ -323,7 +323,7 @@ impl<T, S> HashSet<T, S>
/// let diff: HashSet<_> = b.difference(&a).collect(); /// let diff: HashSet<_> = b.difference(&a).collect();
/// assert_eq!(diff, [4].iter().collect()); /// assert_eq!(diff, [4].iter().collect());
/// ``` /// ```
pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> { pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
Difference { Difference {
iter: self.iter(), iter: self.iter(),
other, other,
@ -351,7 +351,7 @@ impl<T, S> HashSet<T, S>
/// assert_eq!(diff1, diff2); /// assert_eq!(diff1, diff2);
/// assert_eq!(diff1, [1, 4].iter().collect()); /// assert_eq!(diff1, [1, 4].iter().collect());
/// ``` /// ```
pub fn symmetric_difference<'a>(&'a self, pub fn symmetric_difference<'a>(&'a self,
other: &'a HashSet<T, S>) other: &'a HashSet<T, S>)
-> SymmetricDifference<'a, T, S> { -> SymmetricDifference<'a, T, S> {
SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
@ -375,7 +375,7 @@ impl<T, S> HashSet<T, S>
/// let intersection: HashSet<_> = a.intersection(&b).collect(); /// let intersection: HashSet<_> = a.intersection(&b).collect();
/// assert_eq!(intersection, [2, 3].iter().collect()); /// assert_eq!(intersection, [2, 3].iter().collect());
/// ``` /// ```
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> { pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
Intersection { Intersection {
iter: self.iter(), iter: self.iter(),
other, other,
@ -400,7 +400,7 @@ impl<T, S> HashSet<T, S>
/// let union: HashSet<_> = a.union(&b).collect(); /// let union: HashSet<_> = a.union(&b).collect();
/// assert_eq!(union, [1, 2, 3, 4].iter().collect()); /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
/// ``` /// ```
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> { pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
Union { iter: self.iter().chain(other.difference(self)) } Union { iter: self.iter().chain(other.difference(self)) }
} }
@ -416,7 +416,7 @@ impl<T, S> HashSet<T, S>
/// v.insert(1); /// v.insert(1);
/// assert_eq!(v.len(), 1); /// assert_eq!(v.len(), 1);
/// ``` /// ```
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.map.len() self.map.len()
} }
@ -432,7 +432,7 @@ impl<T, S> HashSet<T, S>
/// v.insert(1); /// v.insert(1);
/// assert!(!v.is_empty()); /// assert!(!v.is_empty());
/// ``` /// ```
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.map.is_empty() self.map.is_empty()
} }
@ -454,7 +454,7 @@ impl<T, S> HashSet<T, S>
/// assert!(set.is_empty()); /// assert!(set.is_empty());
/// ``` /// ```
#[inline] #[inline]
pub fn drain(&mut self) -> Drain<T> { pub fn drain(&mut self) -> Drain<T> {
Drain { iter: self.map.drain() } Drain { iter: self.map.drain() }
} }
@ -470,7 +470,7 @@ impl<T, S> HashSet<T, S>
/// v.clear(); /// v.clear();
/// assert!(v.is_empty()); /// assert!(v.is_empty());
/// ``` /// ```
pub fn clear(&mut self) { pub fn clear(&mut self) where T: 'static {
self.map.clear() self.map.clear()
} }
@ -492,7 +492,7 @@ impl<T, S> HashSet<T, S>
/// ///
/// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html /// [`Hash`]: ../../std/hash/trait.Hash.html
pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
where T: Borrow<Q>, where T: Borrow<Q>,
Q: Hash + Eq Q: Hash + Eq
{ {
@ -507,7 +507,7 @@ impl<T, S> HashSet<T, S>
/// ///
/// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html /// [`Hash`]: ../../std/hash/trait.Hash.html
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where T: Borrow<Q>, where T: Borrow<Q>,
Q: Hash + Eq Q: Hash + Eq
{ {
@ -531,7 +531,7 @@ impl<T, S> HashSet<T, S>
/// b.insert(1); /// b.insert(1);
/// assert_eq!(a.is_disjoint(&b), false); /// assert_eq!(a.is_disjoint(&b), false);
/// ``` /// ```
pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool { pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
self.iter().all(|v| !other.contains(v)) self.iter().all(|v| !other.contains(v))
} }
@ -552,7 +552,7 @@ impl<T, S> HashSet<T, S>
/// set.insert(4); /// set.insert(4);
/// assert_eq!(set.is_subset(&sup), false); /// assert_eq!(set.is_subset(&sup), false);
/// ``` /// ```
pub fn is_subset(&self, other: &HashSet<T, S>) -> bool { pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
self.iter().all(|v| other.contains(v)) self.iter().all(|v| other.contains(v))
} }
@ -577,7 +577,7 @@ impl<T, S> HashSet<T, S>
/// assert_eq!(set.is_superset(&sub), true); /// assert_eq!(set.is_superset(&sub), true);
/// ``` /// ```
#[inline] #[inline]
pub fn is_superset(&self, other: &HashSet<T, S>) -> bool { pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
other.is_subset(self) other.is_subset(self)
} }
@ -598,13 +598,13 @@ impl<T, S> HashSet<T, S>
/// assert_eq!(set.insert(2), false); /// assert_eq!(set.insert(2), false);
/// assert_eq!(set.len(), 1); /// assert_eq!(set.len(), 1);
/// ``` /// ```
pub fn insert(&mut self, value: T) -> bool { pub fn insert(&mut self, value: T) -> bool {
self.map.insert(value, ()).is_none() self.map.insert(value, ()).is_none()
} }
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
/// one. Returns the replaced value. /// one. Returns the replaced value.
pub fn replace(&mut self, value: T) -> Option<T> { pub fn replace(&mut self, value: T) -> Option<T> {
Recover::replace(&mut self.map, value) Recover::replace(&mut self.map, value)
} }
@ -629,7 +629,7 @@ impl<T, S> HashSet<T, S>
/// ///
/// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html /// [`Hash`]: ../../std/hash/trait.Hash.html
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
where T: Borrow<Q>, where T: Borrow<Q>,
Q: Hash + Eq Q: Hash + Eq
{ {
@ -644,7 +644,7 @@ impl<T, S> HashSet<T, S>
/// ///
/// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html /// [`Hash`]: ../../std/hash/trait.Hash.html
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
where T: Borrow<Q>, where T: Borrow<Q>,
Q: Hash + Eq Q: Hash + Eq
{ {
@ -665,7 +665,7 @@ impl<T, S> HashSet<T, S>
/// set.retain(|&k| k % 2 == 0); /// set.retain(|&k| k % 2 == 0);
/// assert_eq!(set.len(), 3); /// assert_eq!(set.len(), 3);
/// ``` /// ```
pub fn retain<F>(&mut self, mut f: F) pub fn retain<F>(&mut self, mut f: F)
where F: FnMut(&T) -> bool where F: FnMut(&T) -> bool
{ {
self.map.retain(|k, _| f(k)); self.map.retain(|k, _| f(k));
@ -892,7 +892,7 @@ pub struct IntoIter<K> {
/// ///
/// [`HashSet`]: struct.HashSet.html /// [`HashSet`]: struct.HashSet.html
/// [`drain`]: struct.HashSet.html#method.drain /// [`drain`]: struct.HashSet.html#method.drain
pub struct Drain<'a, K: 'a> { pub struct Drain<'a, K: 'static> {
iter: map::Drain<'a, K, ()>, iter: map::Drain<'a, K, ()>,
} }

View file

@ -16,7 +16,8 @@ use marker;
use mem::{align_of, size_of}; use mem::{align_of, size_of};
use mem; use mem;
use ops::{Deref, DerefMut}; use ops::{Deref, DerefMut};
use ptr::{self, Unique, Shared}; use ptr;
use shim::{Unique, Shared};
use self::BucketState::*; use self::BucketState::*;
@ -997,7 +998,7 @@ impl<K, V> IntoIter<K, V> {
} }
/// Iterator over the entries in a table, clearing the table. /// Iterator over the entries in a table, clearing the table.
pub struct Drain<'a, K: 'a, V: 'a> { pub struct Drain<'a, K: 'static, V: 'static> {
table: Shared<RawTable<K, V>>, table: Shared<RawTable<K, V>>,
iter: RawBuckets<'static, K, V>, iter: RawBuckets<'static, K, V>,
marker: marker::PhantomData<&'a RawTable<K, V>>, marker: marker::PhantomData<&'a RawTable<K, V>>,
@ -1105,7 +1106,7 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
} }
} }
impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> { impl<'a, K: 'static, V: 'static> Drop for Drain<'a, K, V> {
fn drop(&mut self) { fn drop(&mut self) {
for _ in self {} for _ in self {}
} }

View file

@ -1,5 +1,5 @@
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(alloc, shared, unique)] #![feature(alloc)]
extern crate alloc; extern crate alloc;
@ -16,3 +16,66 @@ pub mod hash_map {
pub mod hash_set { pub mod hash_set {
pub use super::impls::set::*; pub use super::impls::set::*;
} }
mod shim {
use std::marker::PhantomData;
pub struct NonZeroPtr<T: 'static>(&'static T);
impl<T: 'static> NonZeroPtr<T> {
pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
NonZeroPtr(&*ptr)
}
pub fn as_ptr(&self) -> *mut T {
self.0 as *const T as *mut T
}
}
pub struct Unique<T: 'static> {
ptr: NonZeroPtr<T>,
_marker: PhantomData<T>,
}
impl<T: 'static> Unique<T> {
pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
Unique {
ptr: NonZeroPtr::new_unchecked(ptr),
_marker: PhantomData,
}
}
pub fn as_ptr(&self) -> *mut T {
self.ptr.as_ptr()
}
}
unsafe impl<T: Send + 'static> Send for Unique<T> { }
unsafe impl<T: Sync + 'static> Sync for Unique<T> { }
pub struct Shared<T: 'static> {
ptr: NonZeroPtr<T>,
_marker: PhantomData<T>,
// force it to be !Send/!Sync
_marker2: PhantomData<*const u8>,
}
impl<T: 'static> Shared<T> {
pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
Shared {
ptr: NonZeroPtr::new_unchecked(ptr),
_marker: PhantomData,
_marker2: PhantomData,
}
}
pub unsafe fn as_mut(&self) -> &mut T {
&mut *self.ptr.as_ptr()
}
}
impl<'a, T> From<&'a mut T> for Shared<T> {
fn from(reference: &'a mut T) -> Self {
unsafe { Shared::new_unchecked(reference) }
}
}
}