From 2b996112911fad41d8af4daa591f58d621047047 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 25 Aug 2017 16:22:11 -0700 Subject: [PATCH] Kill unique and shared --- src/hash/map.rs | 6 ++--- src/hash/set.rs | 56 ++++++++++++++++++++-------------------- src/hash/table.rs | 7 ++--- src/lib.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 35 deletions(-) diff --git a/src/hash/map.rs b/src/hash/map.rs index f2a03a21a90..8136e9df327 100644 --- a/src/hash/map.rs +++ b/src/hash/map.rs @@ -1035,7 +1035,7 @@ impl HashMap /// assert!(a.is_empty()); /// ``` #[inline] - pub fn drain(&mut self) -> Drain { + pub fn drain(&mut self) -> Drain where K: 'static, V: 'static { Drain { inner: self.table.drain() } } @@ -1053,7 +1053,7 @@ impl HashMap /// assert!(a.is_empty()); /// ``` #[inline] - pub fn clear(&mut self) { + pub fn clear(&mut self) where K: 'static, V: 'static { self.drain(); } @@ -1409,7 +1409,7 @@ impl<'a, K, V: Debug> fmt::Debug for Values<'a, K, V> { /// /// [`drain`]: struct.HashMap.html#method.drain /// [`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>, } diff --git a/src/hash/set.rs b/src/hash/set.rs index f96389bcfdc..d27deaa190c 100644 --- a/src/hash/set.rs +++ b/src/hash/set.rs @@ -131,7 +131,7 @@ impl HashSet { /// let set: HashSet = HashSet::new(); /// ``` #[inline] - pub fn new() -> HashSet { + pub fn new() -> HashSet { HashSet { map: HashMap::new() } } @@ -148,7 +148,7 @@ impl HashSet { /// assert!(set.capacity() >= 10); /// ``` #[inline] - pub fn with_capacity(capacity: usize) -> HashSet { + pub fn with_capacity(capacity: usize) -> HashSet { HashSet { map: HashMap::with_capacity(capacity) } } } @@ -178,7 +178,7 @@ impl HashSet /// set.insert(2); /// ``` #[inline] - pub fn with_hasher(hasher: S) -> HashSet { + pub fn with_hasher(hasher: S) -> HashSet { HashSet { map: HashMap::with_hasher(hasher) } } @@ -204,7 +204,7 @@ impl HashSet /// set.insert(1); /// ``` #[inline] - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) } } @@ -222,7 +222,7 @@ impl HashSet /// let set: HashSet = HashSet::with_hasher(hasher); /// let hasher: &RandomState = set.hasher(); /// ``` - pub fn hasher(&self) -> &S { + pub fn hasher(&self) -> &S { self.map.hasher() } @@ -236,7 +236,7 @@ impl HashSet /// assert!(set.capacity() >= 100); /// ``` #[inline] - pub fn capacity(&self) -> usize { + pub fn capacity(&self) -> usize { self.map.capacity() } @@ -256,7 +256,7 @@ impl HashSet /// set.reserve(10); /// assert!(set.capacity() >= 10); /// ``` - pub fn reserve(&mut self, additional: usize) { + pub fn reserve(&mut self, additional: usize) { self.map.reserve(additional) } @@ -276,7 +276,7 @@ impl HashSet /// set.shrink_to_fit(); /// assert!(set.capacity() >= 2); /// ``` - pub fn shrink_to_fit(&mut self) { + pub fn shrink_to_fit(&mut self) { self.map.shrink_to_fit() } @@ -296,7 +296,7 @@ impl HashSet /// println!("{}", x); /// } /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { Iter { iter: self.map.keys() } } @@ -323,7 +323,7 @@ impl HashSet /// let diff: HashSet<_> = b.difference(&a).collect(); /// assert_eq!(diff, [4].iter().collect()); /// ``` - pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { Difference { iter: self.iter(), other, @@ -351,7 +351,7 @@ impl HashSet /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 4].iter().collect()); /// ``` - pub fn symmetric_difference<'a>(&'a self, + pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } @@ -375,7 +375,7 @@ impl HashSet /// let intersection: HashSet<_> = a.intersection(&b).collect(); /// assert_eq!(intersection, [2, 3].iter().collect()); /// ``` - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { Intersection { iter: self.iter(), other, @@ -400,7 +400,7 @@ impl HashSet /// let union: HashSet<_> = a.union(&b).collect(); /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); /// ``` - pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { Union { iter: self.iter().chain(other.difference(self)) } } @@ -416,7 +416,7 @@ impl HashSet /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` - pub fn len(&self) -> usize { + pub fn len(&self) -> usize { self.map.len() } @@ -432,7 +432,7 @@ impl HashSet /// v.insert(1); /// assert!(!v.is_empty()); /// ``` - pub fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { self.map.is_empty() } @@ -454,7 +454,7 @@ impl HashSet /// assert!(set.is_empty()); /// ``` #[inline] - pub fn drain(&mut self) -> Drain { + pub fn drain(&mut self) -> Drain { Drain { iter: self.map.drain() } } @@ -470,7 +470,7 @@ impl HashSet /// v.clear(); /// assert!(v.is_empty()); /// ``` - pub fn clear(&mut self) { + pub fn clear(&mut self) where T: 'static { self.map.clear() } @@ -492,7 +492,7 @@ impl HashSet /// /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html - pub fn contains(&self, value: &Q) -> bool + pub fn contains(&self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq { @@ -507,7 +507,7 @@ impl HashSet /// /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html - pub fn get(&self, value: &Q) -> Option<&T> + pub fn get(&self, value: &Q) -> Option<&T> where T: Borrow, Q: Hash + Eq { @@ -531,7 +531,7 @@ impl HashSet /// b.insert(1); /// assert_eq!(a.is_disjoint(&b), false); /// ``` - pub fn is_disjoint(&self, other: &HashSet) -> bool { + pub fn is_disjoint(&self, other: &HashSet) -> bool { self.iter().all(|v| !other.contains(v)) } @@ -552,7 +552,7 @@ impl HashSet /// set.insert(4); /// assert_eq!(set.is_subset(&sup), false); /// ``` - pub fn is_subset(&self, other: &HashSet) -> bool { + pub fn is_subset(&self, other: &HashSet) -> bool { self.iter().all(|v| other.contains(v)) } @@ -577,7 +577,7 @@ impl HashSet /// assert_eq!(set.is_superset(&sub), true); /// ``` #[inline] - pub fn is_superset(&self, other: &HashSet) -> bool { + pub fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } @@ -598,13 +598,13 @@ impl HashSet /// assert_eq!(set.insert(2), false); /// 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() } /// Adds a value to the set, replacing the existing value, if any, that is equal to the given /// one. Returns the replaced value. - pub fn replace(&mut self, value: T) -> Option { + pub fn replace(&mut self, value: T) -> Option { Recover::replace(&mut self.map, value) } @@ -629,7 +629,7 @@ impl HashSet /// /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html - pub fn remove(&mut self, value: &Q) -> bool + pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq { @@ -644,7 +644,7 @@ impl HashSet /// /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html - pub fn take(&mut self, value: &Q) -> Option + pub fn take(&mut self, value: &Q) -> Option where T: Borrow, Q: Hash + Eq { @@ -665,7 +665,7 @@ impl HashSet /// set.retain(|&k| k % 2 == 0); /// assert_eq!(set.len(), 3); /// ``` - pub fn retain(&mut self, mut f: F) + pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool { self.map.retain(|k, _| f(k)); @@ -892,7 +892,7 @@ pub struct IntoIter { /// /// [`HashSet`]: struct.HashSet.html /// [`drain`]: struct.HashSet.html#method.drain -pub struct Drain<'a, K: 'a> { +pub struct Drain<'a, K: 'static> { iter: map::Drain<'a, K, ()>, } diff --git a/src/hash/table.rs b/src/hash/table.rs index d76d2970ac9..f5a0cf9be7e 100644 --- a/src/hash/table.rs +++ b/src/hash/table.rs @@ -16,7 +16,8 @@ use marker; use mem::{align_of, size_of}; use mem; use ops::{Deref, DerefMut}; -use ptr::{self, Unique, Shared}; +use ptr; +use shim::{Unique, Shared}; use self::BucketState::*; @@ -997,7 +998,7 @@ impl IntoIter { } /// 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>, iter: RawBuckets<'static, K, V>, marker: marker::PhantomData<&'a RawTable>, @@ -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) { for _ in self {} } diff --git a/src/lib.rs b/src/lib.rs index 0a28542c224..3cca486000d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![feature(allocator_api)] -#![feature(alloc, shared, unique)] +#![feature(alloc)] extern crate alloc; @@ -16,3 +16,66 @@ pub mod hash_map { pub mod hash_set { pub use super::impls::set::*; } + +mod shim { + use std::marker::PhantomData; + + pub struct NonZeroPtr(&'static T); + + impl NonZeroPtr { + 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 { + ptr: NonZeroPtr, + _marker: PhantomData, + } + + impl Unique { + 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 Send for Unique { } + + unsafe impl Sync for Unique { } + + pub struct Shared { + ptr: NonZeroPtr, + _marker: PhantomData, + // force it to be !Send/!Sync + _marker2: PhantomData<*const u8>, + } + + impl Shared { + 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 { + fn from(reference: &'a mut T) -> Self { + unsafe { Shared::new_unchecked(reference) } + } + } +}