@@ -17,13 +17,12 @@ use cmp;
1717use hash:: { Hash , Hasher } ;
1818use iter:: { Iterator , IteratorExt , ExactSizeIterator , count} ;
1919use marker:: { Copy , Sized } ;
20- use mem:: { min_align_of, size_of} ;
21- use mem;
20+ use mem:: { self , min_align_of, size_of} ;
2221use num:: { Int , UnsignedInt } ;
2322use ops:: { Deref , DerefMut , Drop } ;
24- use option:: Option ;
25- use option:: Option :: { Some , None } ;
23+ use option:: Option :: { self , Some , None } ;
2624use ptr:: { self , Unique , PtrExt , copy_memory, copy_nonoverlapping_memory, zero_memory} ;
25+ use result:: Result :: { self , Ok , Err } ;
2726use rt:: heap:: { allocate, deallocate, reallocate_inplace} ;
2827use collections:: hash_state:: HashState ;
2928use core:: nonzero:: NonZero ;
@@ -95,6 +94,7 @@ impl<K,V,M:Copy,S> Copy for Bucket<K,V,M,S> {}
9594mod bucket {
9695 pub enum Empty { }
9796 pub enum Full { }
97+ pub enum TableIsEmpty { }
9898}
9999
100100pub type EmptyBucket < K , V , M > = Bucket < K , V , M , bucket:: Empty > ;
@@ -151,6 +151,14 @@ fn can_alias_safehash_as_option() {
151151 assert_eq ! ( size_of:: <SafeHash >( ) , size_of:: <Option <SafeHash >>( ) )
152152}
153153
154+ impl < K , V > Deref for RawTable < K , V > {
155+ type Target = RawTable < K , V > ;
156+
157+ fn deref ( & self ) -> & RawTable < K , V > {
158+ self
159+ }
160+ }
161+
154162impl < K , V , M > RawBucket < K , V , M > {
155163 unsafe fn offset ( self , count : int ) -> RawBucket < K , V , M > {
156164 RawBucket {
@@ -210,29 +218,47 @@ impl<K, V, M, S> Bucket<K, V, M, S> {
210218 pub fn index ( & self ) -> uint {
211219 self . 0 . idx
212220 }
221+ /// Turn the bucket into an iterator over full buckets.
222+ pub fn into_iter ( self ) -> RawFullBuckets < K , V , M > {
223+ RawFullBuckets {
224+ raw : self . raw ,
225+ hashes_end : unsafe {
226+ self . raw . hash . offset ( self . 0 . capacity as int - self . index ( ) as int )
227+ } ,
228+ table : self . table ,
229+ }
230+ }
213231}
214232
215233impl < K , V , M : Deref < Target =RawTable < K , V > > > Bucket < K , V , M > {
216234 pub fn new ( table : M , hash : SafeHash ) -> Option < Bucket < K , V , M > > {
217- Bucket :: at_index ( table, * hash as usize )
235+ Bucket :: at_index ( table, * hash as usize ) . ok ( )
218236 }
219237
220- pub fn at_index ( table : M , ib_index : uint ) -> Option < Bucket < K , V , M > > {
238+ pub fn at_index ( table : M , ib_index : uint )
239+ -> Result < Bucket < K , V , M > , Bucket < K , V , M , bucket:: TableIsEmpty > >
240+ {
241+ let ib_index = ib_index & ( table. capacity ( ) - 1 ) ;
242+ let bb = BareBucket {
243+ raw : unsafe {
244+ table. first_bucket_raw ( ) . offset ( ib_index as int )
245+ } ,
246+ idx : ib_index,
247+ capacity : table. capacity ( ) ,
248+ table : table,
249+ } ;
250+
221251 if table. capacity ( ) == 0 {
222- None
252+ Err ( Bucket ( bb ) )
223253 } else {
224- let ib_index = ib_index & ( table. capacity ( ) - 1 ) ;
225- Some ( Bucket ( BareBucket {
226- raw : unsafe {
227- table. first_bucket_raw ( ) . offset ( ib_index as int )
228- } ,
229- idx : ib_index,
230- capacity : table. capacity ( ) ,
231- table : table
232- } ) )
254+ Ok ( Bucket ( bb) )
233255 }
234256 }
235257
258+ pub fn raw_full_buckets ( table : M ) -> RawFullBuckets < K , V , M > {
259+ Bucket :: at_index ( table, 0 ) . map ( |b| b. into_iter ( ) ) . unwrap_or_else ( |b| b. into_iter ( ) )
260+ }
261+
236262 /// Narrows down the range of iteration, which must be a power of 2.
237263 pub fn iter_to ( mut self , limit : usize ) -> Bucket < K , V , M > {
238264 assert ! ( limit <= self . capacity) ;
@@ -461,7 +487,7 @@ impl<K, V> RawTable<K, V> {
461487 }
462488
463489 #[ inline]
464- fn first_bucket_raw < M > ( & self ) -> RawBucket < K , V , M > {
490+ unsafe fn first_bucket_raw < M > ( & self ) -> RawBucket < K , V , M > {
465491 if self . capacity ( ) == 0 {
466492 RawBucket {
467493 hash : ptr:: null_mut ( ) ,
@@ -539,18 +565,10 @@ impl<K, V> RawTable<K, V> {
539565 self . size
540566 }
541567
542- pub fn raw_full_buckets ( & self ) -> RawFullBuckets < K , V , & RawTable < K , V > > {
543- full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
544- }
545-
546- pub fn raw_full_buckets_mut ( & mut self ) -> RawFullBuckets < K , V , & mut RawTable < K , V > > {
547- full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
548- }
549-
550568 pub fn into_iter ( self ) -> IntoIter < K , V > {
551569 // Replace the marker regardless of lifetime bounds on parameters.
552570 IntoIter {
553- iter : full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
571+ iter : Bucket :: raw_full_buckets ( self ) ,
554572 }
555573 }
556574}
@@ -596,14 +614,7 @@ fn align<K, V>() -> usize {
596614 cmp:: max ( mem:: min_align_of :: < ( K , V ) > ( ) , mem:: min_align_of :: < u64 > ( ) )
597615}
598616
599- pub fn full_buckets < K , V , M > ( raw : RawBucket < K , V , M > , cap : usize , t : M ) -> RawFullBuckets < K , V , M > {
600- RawFullBuckets {
601- raw : raw,
602- hashes_end : unsafe { raw. hash . offset ( cap as int ) } ,
603- table : t,
604- }
605- }
606-
617+ /// A newtyped RawBucket. Not copyable.
607618pub struct RawFullBucket < K , V , M > ( RawBucket < K , V , M > ) ;
608619
609620impl < K , V , M > Deref for RawFullBucket < K , V , M > {
@@ -670,7 +681,7 @@ impl<K, V> Iterator for IntoIter<K, V> {
670681 self . iter . next ( ) . map ( |bucket| {
671682 self . iter . table . size -= 1 ;
672683 unsafe {
673- let ( k, v) = ptr:: read ( bucket. kval as * const ( K , V ) ) ;
684+ let ( k, v) = ptr:: read ( bucket. kval ) ;
674685 ( * ( bucket. hash as * mut SafeHash ) , k, v)
675686 }
676687 } )
@@ -742,8 +753,8 @@ impl<K, V> Drop for RawTable<K, V> {
742753 // Avoid double drop of elements that have been already moved out.
743754 unsafe {
744755 if self . size != 0 {
745- for bucket in self . raw_full_buckets_mut ( ) {
746- ptr:: read ( bucket. kval as * const ( K , V ) ) ;
756+ for bucket in Bucket :: raw_full_buckets ( self ) {
757+ ptr:: read ( bucket. kval ) ;
747758 }
748759 }
749760 }
0 commit comments