@@ -1073,6 +1073,24 @@ where
10731073 }
10741074 }
10751075
1076+ /// A version of [`iter_mut`](Self::iter_mut) which is variant over
1077+ /// elements, and thus unsafe.
1078+ ///
1079+ /// See the documentation for [`IterUnsafeMut`] for more information on how
1080+ /// to correctly use this.
1081+ ///
1082+ /// # Safety
1083+ ///
1084+ /// Any part of the returned elements which is mutated must be made invariant.
1085+ /// See the documentation for [`IterUnsafeMut`] for an example and further
1086+ /// explanation.
1087+ pub unsafe fn iter_unsafe_mut ( & mut self ) -> IterUnsafeMut < ' _ , T > {
1088+ IterUnsafeMut {
1089+ inner : unsafe { self . raw . iter ( ) } ,
1090+ marker : PhantomData ,
1091+ }
1092+ }
1093+
10761094 /// An iterator producing the `usize` indices of all occupied buckets.
10771095 ///
10781096 /// The order in which the iterator yields indices is unspecified
@@ -2510,6 +2528,16 @@ pub struct IterMut<'a, T> {
25102528 inner : RawIter < T > ,
25112529 marker : PhantomData < & ' a mut T > ,
25122530}
2531+ impl < ' a , T > IterMut < ' a , T > {
2532+ /// Returns a iterator of references over the remaining items.
2533+ #[ cfg_attr( feature = "inline-more" , inline) ]
2534+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2535+ Iter {
2536+ inner : self . inner . clone ( ) ,
2537+ marker : PhantomData ,
2538+ }
2539+ }
2540+ }
25132541
25142542impl < T > Default for IterMut < ' _ , T > {
25152543 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2558,12 +2586,113 @@ where
25582586 T : fmt:: Debug ,
25592587{
25602588 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2561- f. debug_list ( )
2562- . entries ( Iter {
2563- inner : self . inner . clone ( ) ,
2564- marker : PhantomData ,
2565- } )
2566- . finish ( )
2589+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2590+ }
2591+ }
2592+
2593+ /// An unsafe version of [`IterMut`] which is *variant* over `T`.
2594+ ///
2595+ /// This is used for implementations of mutable iterators where mutation is only
2596+ /// allowed on part of the value in the table. For example, a mutable iterator
2597+ /// for a map may return an immutable key alongside a mutable value, even though
2598+ /// these are both stored inside the table.
2599+ ///
2600+ /// # Safety
2601+ ///
2602+ /// In order to correctly use this iterator, it should be wrapped in a safe
2603+ /// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2604+ /// correct variance.
2605+ ///
2606+ /// For example, a [`hash_map::IterMut`] implementation correctly returning
2607+ /// a variant key, and an invariant value:
2608+ ///
2609+ /// [`hash_map::IterMut`]: crate::hash_map::IterMut
2610+ ///
2611+ /// ```rust
2612+ /// use core::marker::PhantomData;
2613+ /// use hashbrown::hash_table;
2614+ ///
2615+ /// pub struct IterMut<'a, K, V> {
2616+ /// inner: hash_table::IterMut<'a, (K, V)>,
2617+ /// // Variant over keys, invariant over values
2618+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2619+ /// }
2620+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2621+ /// // Immutable keys, mutable values
2622+ /// type Item = (&'a K, &'a mut V);
2623+ ///
2624+ /// fn next(&mut self) -> Option<Self::Item> {
2625+ /// // Even though the key is mutably borrowed here, this is sound
2626+ /// // because we never actually mutate the key before yielding the
2627+ /// // immutable reference
2628+ /// let (ref key, ref mut val) = self.inner.next()?;
2629+ /// Some((key, val))
2630+ /// }
2631+ /// }
2632+ /// ```
2633+ pub struct IterUnsafeMut < ' a , T > {
2634+ inner : RawIter < T > ,
2635+ marker : PhantomData < & ' a T > ,
2636+ }
2637+ impl < ' a , T > IterUnsafeMut < ' a , T > {
2638+ /// Returns a iterator of references over the remaining items.
2639+ #[ cfg_attr( feature = "inline-more" , inline) ]
2640+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2641+ Iter {
2642+ inner : self . inner . clone ( ) ,
2643+ marker : PhantomData ,
2644+ }
2645+ }
2646+ }
2647+
2648+ impl < T > Default for IterUnsafeMut < ' _ , T > {
2649+ #[ cfg_attr( feature = "inline-more" , inline) ]
2650+ fn default ( ) -> Self {
2651+ IterUnsafeMut {
2652+ inner : Default :: default ( ) ,
2653+ marker : PhantomData ,
2654+ }
2655+ }
2656+ }
2657+ impl < ' a , T > Iterator for IterUnsafeMut < ' a , T > {
2658+ type Item = & ' a mut T ;
2659+
2660+ fn next ( & mut self ) -> Option < Self :: Item > {
2661+ // Avoid `Option::map` because it bloats LLVM IR.
2662+ match self . inner . next ( ) {
2663+ Some ( bucket) => Some ( unsafe { bucket. as_mut ( ) } ) ,
2664+ None => None ,
2665+ }
2666+ }
2667+
2668+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2669+ self . inner . size_hint ( )
2670+ }
2671+
2672+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2673+ where
2674+ Self : Sized ,
2675+ F : FnMut ( B , Self :: Item ) -> B ,
2676+ {
2677+ self . inner
2678+ . fold ( init, |acc, bucket| unsafe { f ( acc, bucket. as_mut ( ) ) } )
2679+ }
2680+ }
2681+
2682+ impl < T > ExactSizeIterator for IterUnsafeMut < ' _ , T > {
2683+ fn len ( & self ) -> usize {
2684+ self . inner . len ( )
2685+ }
2686+ }
2687+
2688+ impl < T > FusedIterator for IterUnsafeMut < ' _ , T > { }
2689+
2690+ impl < T > fmt:: Debug for IterUnsafeMut < ' _ , T >
2691+ where
2692+ T : fmt:: Debug ,
2693+ {
2694+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2695+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
25672696 }
25682697}
25692698
@@ -2817,6 +2946,19 @@ where
28172946{
28182947 inner : RawIntoIter < T , A > ,
28192948}
2949+ impl < T , A > IntoIter < T , A >
2950+ where
2951+ A : Allocator ,
2952+ {
2953+ /// Returns a iterator of references over the remaining items.
2954+ #[ cfg_attr( feature = "inline-more" , inline) ]
2955+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2956+ Iter {
2957+ inner : self . inner . iter ( ) ,
2958+ marker : PhantomData ,
2959+ }
2960+ }
2961+ }
28202962
28212963impl < T , A : Allocator > Default for IntoIter < T , A > {
28222964 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2867,12 +3009,7 @@ where
28673009 A : Allocator ,
28683010{
28693011 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2870- f. debug_list ( )
2871- . entries ( Iter {
2872- inner : self . inner . iter ( ) ,
2873- marker : PhantomData ,
2874- } )
2875- . finish ( )
3012+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
28763013 }
28773014}
28783015
@@ -2886,6 +3023,16 @@ where
28863023pub struct Drain < ' a , T , A : Allocator = Global > {
28873024 inner : RawDrain < ' a , T , A > ,
28883025}
3026+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3027+ /// Returns a iterator of references over the remaining items.
3028+ #[ cfg_attr( feature = "inline-more" , inline) ]
3029+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3030+ Iter {
3031+ inner : self . inner . iter ( ) ,
3032+ marker : PhantomData ,
3033+ }
3034+ }
3035+ }
28893036
28903037impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
28913038 type Item = T ;
@@ -2917,12 +3064,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29173064
29183065impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29193066 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2920- f. debug_list ( )
2921- . entries ( Iter {
2922- inner : self . inner . iter ( ) ,
2923- marker : PhantomData ,
2924- } )
2925- . finish ( )
3067+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29263068 }
29273069}
29283070
0 commit comments