@@ -1071,6 +1071,24 @@ where
10711071 }
10721072 }
10731073
1074+ /// A version of [`iter_mut`](Self::iter_mut) which is variant over
1075+ /// elements, and thus unsafe.
1076+ ///
1077+ /// See the documentation for [`IterUnsafeMut`] for more information on how
1078+ /// to correctly use this.
1079+ ///
1080+ /// # Safety
1081+ ///
1082+ /// Any part of the returned elements which is mutated must be made invariant.
1083+ /// See the documentation for [`IterUnsafeMut`] for an example and further
1084+ /// explanation.
1085+ pub unsafe fn iter_unsafe_mut ( & mut self ) -> IterUnsafeMut < ' _ , T > {
1086+ IterUnsafeMut {
1087+ inner : unsafe { self . raw . iter ( ) } ,
1088+ marker : PhantomData ,
1089+ }
1090+ }
1091+
10741092 /// An iterator producing the `usize` indices of all occupied buckets.
10751093 ///
10761094 /// The order in which the iterator yields indices is unspecified
@@ -2504,6 +2522,16 @@ pub struct IterMut<'a, T> {
25042522 inner : RawIter < T > ,
25052523 marker : PhantomData < & ' a mut T > ,
25062524}
2525+ impl < ' a , T > IterMut < ' a , T > {
2526+ /// Returns a iterator of references over the remaining items.
2527+ #[ cfg_attr( feature = "inline-more" , inline) ]
2528+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2529+ Iter {
2530+ inner : self . inner . clone ( ) ,
2531+ marker : PhantomData ,
2532+ }
2533+ }
2534+ }
25072535
25082536impl < T > Default for IterMut < ' _ , T > {
25092537 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2552,15 +2580,112 @@ where
25522580 T : fmt:: Debug ,
25532581{
25542582 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2555- f. debug_list ( )
2556- . entries ( Iter {
2557- inner : self . inner . clone ( ) ,
2558- marker : PhantomData ,
2559- } )
2560- . finish ( )
2583+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2584+ }
2585+ }
2586+
2587+ /// An unsafe version of [`IterMut`] which is *variant* over `T`.
2588+ ///
2589+ /// This is used for implementations of mutable iterators where mutation is only
2590+ /// allowed on part of the value in the table. For example, a mutable iterator
2591+ /// for a map may return an immutable key alongside a mutable value, even though
2592+ /// these are both stored inside the table.
2593+ ///
2594+ /// # Safety
2595+ ///
2596+ /// In order to correctly use this iterator, it should be wrapped in a safe
2597+ /// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2598+ /// correct variance.
2599+ ///
2600+ /// For example, a [`hash_map::IterMut`] implementation correctly returning
2601+ /// a variant key, and an invariant value:
2602+ ///
2603+ /// ```rust
2604+ /// pub struct IterMut<'a, K, V> {
2605+ /// inner: hash_table::IterMut<'a, (K, V)>,
2606+ /// // Variant over keys, invariant over values
2607+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2608+ /// }
2609+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2610+ /// // Immutable keys, mutable values
2611+ /// type Item = (&'a K, &'a mut V);
2612+ ///
2613+ /// fn next(&mut self) -> Option<Self::Item> {
2614+ /// // Even though the key is mutably borrowed here, this is sound
2615+ /// // because we never actually mutate the key before yielding the
2616+ /// // immutable reference
2617+ /// let (ref key, ref mut val) = self.inner.next()?;
2618+ /// Some((key, val))
2619+ /// }
2620+ /// }
2621+ /// ```
2622+ pub struct IterUnsafeMut < ' a , T > {
2623+ inner : RawIter < T > ,
2624+ marker : PhantomData < & ' a T > ,
2625+ }
2626+ impl < ' a , T > IterUnsafeMut < ' a , T > {
2627+ /// Returns a iterator of references over the remaining items.
2628+ #[ cfg_attr( feature = "inline-more" , inline) ]
2629+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2630+ Iter {
2631+ inner : self . inner . clone ( ) ,
2632+ marker : PhantomData ,
2633+ }
2634+ }
2635+ }
2636+
2637+ impl < T > Default for IterUnsafeMut < ' _ , T > {
2638+ #[ cfg_attr( feature = "inline-more" , inline) ]
2639+ fn default ( ) -> Self {
2640+ IterUnsafeMut {
2641+ inner : Default :: default ( ) ,
2642+ marker : PhantomData ,
2643+ }
2644+ }
2645+ }
2646+ impl < ' a , T > Iterator for IterUnsafeMut < ' a , T > {
2647+ type Item = & ' a mut T ;
2648+
2649+ fn next ( & mut self ) -> Option < Self :: Item > {
2650+ // Avoid `Option::map` because it bloats LLVM IR.
2651+ match self . inner . next ( ) {
2652+ Some ( bucket) => Some ( unsafe { bucket. as_mut ( ) } ) ,
2653+ None => None ,
2654+ }
2655+ }
2656+
2657+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2658+ self . inner . size_hint ( )
2659+ }
2660+
2661+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2662+ where
2663+ Self : Sized ,
2664+ F : FnMut ( B , Self :: Item ) -> B ,
2665+ {
2666+ self . inner
2667+ . fold ( init, |acc, bucket| unsafe { f ( acc, bucket. as_mut ( ) ) } )
2668+ }
2669+ }
2670+
2671+ impl < T > ExactSizeIterator for IterUnsafeMut < ' _ , T > {
2672+ fn len ( & self ) -> usize {
2673+ self . inner . len ( )
25612674 }
25622675}
25632676
2677+ impl < T > FusedIterator for IterUnsafeMut < ' _ , T > { }
2678+
2679+ impl < T > fmt:: Debug for IterUnsafeMut < ' _ , T >
2680+ where
2681+ T : fmt:: Debug ,
2682+ {
2683+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2684+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2685+ }
2686+ }
2687+
2688+
25642689/// An iterator producing the `usize` indices of all occupied buckets,
25652690/// within the range `0..table.num_buckets()`.
25662691///
@@ -2811,6 +2936,19 @@ where
28112936{
28122937 inner : RawIntoIter < T , A > ,
28132938}
2939+ impl < T , A > IntoIter < T , A >
2940+ where
2941+ A : Allocator ,
2942+ {
2943+ /// Returns a iterator of references over the remaining items.
2944+ #[ cfg_attr( feature = "inline-more" , inline) ]
2945+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2946+ Iter {
2947+ inner : self . inner . iter ( ) ,
2948+ marker : PhantomData ,
2949+ }
2950+ }
2951+ }
28142952
28152953impl < T , A : Allocator > Default for IntoIter < T , A > {
28162954 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2861,12 +2999,7 @@ where
28612999 A : Allocator ,
28623000{
28633001 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2864- f. debug_list ( )
2865- . entries ( Iter {
2866- inner : self . inner . iter ( ) ,
2867- marker : PhantomData ,
2868- } )
2869- . finish ( )
3002+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
28703003 }
28713004}
28723005
@@ -2880,6 +3013,16 @@ where
28803013pub struct Drain < ' a , T , A : Allocator = Global > {
28813014 inner : RawDrain < ' a , T , A > ,
28823015}
3016+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3017+ /// Returns a iterator of references over the remaining items.
3018+ #[ cfg_attr( feature = "inline-more" , inline) ]
3019+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3020+ Iter {
3021+ inner : self . inner . iter ( ) ,
3022+ marker : PhantomData ,
3023+ }
3024+ }
3025+ }
28833026
28843027impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
28853028 type Item = T ;
@@ -2911,12 +3054,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29113054
29123055impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29133056 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2914- f. debug_list ( )
2915- . entries ( Iter {
2916- inner : self . inner . iter ( ) ,
2917- marker : PhantomData ,
2918- } )
2919- . finish ( )
3057+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29203058 }
29213059}
29223060
0 commit comments