@@ -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,12 +2580,113 @@ 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+ /// [`hash_map::IterMut`]: crate::hash_map::IterMut
2604+ ///
2605+ /// ```rust
2606+ /// use core::marker::PhantomData;
2607+ /// use hashbrown::hash_table;
2608+ ///
2609+ /// pub struct IterMut<'a, K, V> {
2610+ /// inner: hash_table::IterMut<'a, (K, V)>,
2611+ /// // Variant over keys, invariant over values
2612+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2613+ /// }
2614+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2615+ /// // Immutable keys, mutable values
2616+ /// type Item = (&'a K, &'a mut V);
2617+ ///
2618+ /// fn next(&mut self) -> Option<Self::Item> {
2619+ /// // Even though the key is mutably borrowed here, this is sound
2620+ /// // because we never actually mutate the key before yielding the
2621+ /// // immutable reference
2622+ /// let (ref key, ref mut val) = self.inner.next()?;
2623+ /// Some((key, val))
2624+ /// }
2625+ /// }
2626+ /// ```
2627+ pub struct IterUnsafeMut < ' a , T > {
2628+ inner : RawIter < T > ,
2629+ marker : PhantomData < & ' a T > ,
2630+ }
2631+ impl < ' a , T > IterUnsafeMut < ' a , T > {
2632+ /// Returns a iterator of references over the remaining items.
2633+ #[ cfg_attr( feature = "inline-more" , inline) ]
2634+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2635+ Iter {
2636+ inner : self . inner . clone ( ) ,
2637+ marker : PhantomData ,
2638+ }
2639+ }
2640+ }
2641+
2642+ impl < T > Default for IterUnsafeMut < ' _ , T > {
2643+ #[ cfg_attr( feature = "inline-more" , inline) ]
2644+ fn default ( ) -> Self {
2645+ IterUnsafeMut {
2646+ inner : Default :: default ( ) ,
2647+ marker : PhantomData ,
2648+ }
2649+ }
2650+ }
2651+ impl < ' a , T > Iterator for IterUnsafeMut < ' a , T > {
2652+ type Item = & ' a mut T ;
2653+
2654+ fn next ( & mut self ) -> Option < Self :: Item > {
2655+ // Avoid `Option::map` because it bloats LLVM IR.
2656+ match self . inner . next ( ) {
2657+ Some ( bucket) => Some ( unsafe { bucket. as_mut ( ) } ) ,
2658+ None => None ,
2659+ }
2660+ }
2661+
2662+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2663+ self . inner . size_hint ( )
2664+ }
2665+
2666+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2667+ where
2668+ Self : Sized ,
2669+ F : FnMut ( B , Self :: Item ) -> B ,
2670+ {
2671+ self . inner
2672+ . fold ( init, |acc, bucket| unsafe { f ( acc, bucket. as_mut ( ) ) } )
2673+ }
2674+ }
2675+
2676+ impl < T > ExactSizeIterator for IterUnsafeMut < ' _ , T > {
2677+ fn len ( & self ) -> usize {
2678+ self . inner . len ( )
2679+ }
2680+ }
2681+
2682+ impl < T > FusedIterator for IterUnsafeMut < ' _ , T > { }
2683+
2684+ impl < T > fmt:: Debug for IterUnsafeMut < ' _ , T >
2685+ where
2686+ T : fmt:: Debug ,
2687+ {
2688+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2689+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
25612690 }
25622691}
25632692
@@ -2811,6 +2940,19 @@ where
28112940{
28122941 inner : RawIntoIter < T , A > ,
28132942}
2943+ impl < T , A > IntoIter < T , A >
2944+ where
2945+ A : Allocator ,
2946+ {
2947+ /// Returns a iterator of references over the remaining items.
2948+ #[ cfg_attr( feature = "inline-more" , inline) ]
2949+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2950+ Iter {
2951+ inner : self . inner . iter ( ) ,
2952+ marker : PhantomData ,
2953+ }
2954+ }
2955+ }
28142956
28152957impl < T , A : Allocator > Default for IntoIter < T , A > {
28162958 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2861,12 +3003,7 @@ where
28613003 A : Allocator ,
28623004{
28633005 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 ( )
3006+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
28703007 }
28713008}
28723009
@@ -2880,6 +3017,16 @@ where
28803017pub struct Drain < ' a , T , A : Allocator = Global > {
28813018 inner : RawDrain < ' a , T , A > ,
28823019}
3020+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3021+ /// Returns a iterator of references over the remaining items.
3022+ #[ cfg_attr( feature = "inline-more" , inline) ]
3023+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3024+ Iter {
3025+ inner : self . inner . iter ( ) ,
3026+ marker : PhantomData ,
3027+ }
3028+ }
3029+ }
28833030
28843031impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
28853032 type Item = T ;
@@ -2911,12 +3058,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29113058
29123059impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29133060 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 ( )
3061+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29203062 }
29213063}
29223064
0 commit comments