1- use core:: { fmt, iter:: FusedIterator , marker:: PhantomData } ;
1+ use core:: { fmt, iter:: FusedIterator , marker:: PhantomData , ptr :: NonNull } ;
22
33use crate :: {
44 control:: Tag ,
@@ -1071,6 +1071,29 @@ where
10711071 }
10721072 }
10731073
1074+ /// An iterator visiting all elements in arbitrary order,
1075+ /// with pointers to the elements.
1076+ /// The iterator element type is `NonNull<T>`.
1077+ ///
1078+ /// This iterator is intended for APIs where only part of the elements are
1079+ /// mutable, with the remainder being immutable. In these cases, wrapping
1080+ /// the ordinary mutable iterator is incorrect because all components of
1081+ /// the element type will be [invariant]. A correct implementation will use
1082+ /// an appropriate [`PhantomData`] marker to make the immutable parts
1083+ /// [covariant] and the mutable parts invariant.
1084+ ///
1085+ /// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
1086+ /// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
1087+ ///
1088+ /// See the documentation for [`UnsafeIter`] for more information on how
1089+ /// to correctly use this.
1090+ pub fn unsafe_iter ( & mut self ) -> UnsafeIter < ' _ , T > {
1091+ UnsafeIter {
1092+ inner : unsafe { self . raw . iter ( ) } ,
1093+ marker : PhantomData ,
1094+ }
1095+ }
1096+
10741097 /// An iterator producing the `usize` indices of all occupied buckets.
10751098 ///
10761099 /// The order in which the iterator yields indices is unspecified
@@ -2581,6 +2604,16 @@ pub struct IterMut<'a, T> {
25812604 inner : RawIter < T > ,
25822605 marker : PhantomData < & ' a mut T > ,
25832606}
2607+ impl < ' a , T > IterMut < ' a , T > {
2608+ /// Returns a iterator of references over the remaining items.
2609+ #[ cfg_attr( feature = "inline-more" , inline) ]
2610+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2611+ Iter {
2612+ inner : self . inner . clone ( ) ,
2613+ marker : PhantomData ,
2614+ }
2615+ }
2616+ }
25842617
25852618impl < T > Default for IterMut < ' _ , T > {
25862619 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2629,12 +2662,124 @@ where
26292662 T : fmt:: Debug ,
26302663{
26312664 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2632- f. debug_list ( )
2633- . entries ( Iter {
2634- inner : self . inner . clone ( ) ,
2635- marker : PhantomData ,
2636- } )
2637- . finish ( )
2665+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2666+ }
2667+ }
2668+
2669+ /// An unsafe iterator over the entries of a `HashTable` in arbitrary order.
2670+ /// The iterator element type is `NonNull<T>`.
2671+ ///
2672+ /// This `struct` is created by the [`unsafe_iter`] method on [`HashTable`].
2673+ ///
2674+ /// This is used for implementations of iterators with "mixed" mutability on
2675+ /// the iterated elements. For example, a mutable iterator for a map may return
2676+ /// an immutable key alongside a mutable value, even though these are both
2677+ /// stored inside the table.
2678+ ///
2679+ /// If you have no idea what any of this means, you probably should be using
2680+ /// [`IterMut`] instead, as it does not have any safety requirements.
2681+ ///
2682+ /// # Safety
2683+ ///
2684+ /// In order to correctly use this iterator, it should be wrapped in a safe
2685+ /// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2686+ /// correct [variance].
2687+ ///
2688+ /// For example, below is a simplified [`hash_map::IterMut`] implementation
2689+ /// that correctly returns a [covariant] key, and an [invariant] value:
2690+ ///
2691+ /// [variance]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance
2692+ /// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
2693+ /// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
2694+ /// [`hash_map::IterMut`]: crate::hash_map::IterMut
2695+ ///
2696+ /// ```rust
2697+ /// use core::marker::PhantomData;
2698+ /// use hashbrown::hash_table;
2699+ ///
2700+ /// pub struct IterMut<'a, K, V> {
2701+ /// inner: hash_table::UnsafeIter<'a, (K, V)>,
2702+ /// // Covariant over keys, invariant over values
2703+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2704+ /// }
2705+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2706+ /// // Immutable keys, mutable values
2707+ /// type Item = (&'a K, &'a mut V);
2708+ ///
2709+ /// fn next(&mut self) -> Option<Self::Item> {
2710+ /// // SAFETY: The lifetime of the dereferenced pointer is derived from
2711+ /// // the lifetime of its iterator, ensuring that it's always valid.
2712+ /// // Additionally, we match the mutability in `self.marker` to ensure
2713+ /// // the correct variance.
2714+ /// let (ref key, ref mut val) = unsafe { *self.inner.next() }?;
2715+ /// Some((key, val))
2716+ /// }
2717+ /// }
2718+ /// ```
2719+ pub struct UnsafeIter < ' a , T > {
2720+ inner : RawIter < T > ,
2721+ marker : PhantomData < & ' a ( ) > ,
2722+ }
2723+ impl < ' a , T > UnsafeIter < ' a , T > {
2724+ /// Returns a iterator of references over the remaining items.
2725+ #[ cfg_attr( feature = "inline-more" , inline) ]
2726+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2727+ Iter {
2728+ inner : self . inner . clone ( ) ,
2729+ marker : PhantomData ,
2730+ }
2731+ }
2732+ }
2733+
2734+ impl < T > Default for UnsafeIter < ' _ , T > {
2735+ #[ cfg_attr( feature = "inline-more" , inline) ]
2736+ fn default ( ) -> Self {
2737+ UnsafeIter {
2738+ inner : Default :: default ( ) ,
2739+ marker : PhantomData ,
2740+ }
2741+ }
2742+ }
2743+ impl < ' a , T > Iterator for UnsafeIter < ' a , T > {
2744+ type Item = NonNull < T > ;
2745+
2746+ fn next ( & mut self ) -> Option < Self :: Item > {
2747+ // Avoid `Option::map` because it bloats LLVM IR.
2748+ match self . inner . next ( ) {
2749+ Some ( bucket) => Some ( unsafe { NonNull :: new_unchecked ( bucket. as_ptr ( ) ) } ) ,
2750+ None => None ,
2751+ }
2752+ }
2753+
2754+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2755+ self . inner . size_hint ( )
2756+ }
2757+
2758+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2759+ where
2760+ Self : Sized ,
2761+ F : FnMut ( B , Self :: Item ) -> B ,
2762+ {
2763+ self . inner . fold ( init, |acc, bucket| unsafe {
2764+ f ( acc, NonNull :: new_unchecked ( bucket. as_ptr ( ) ) )
2765+ } )
2766+ }
2767+ }
2768+
2769+ impl < T > ExactSizeIterator for UnsafeIter < ' _ , T > {
2770+ fn len ( & self ) -> usize {
2771+ self . inner . len ( )
2772+ }
2773+ }
2774+
2775+ impl < T > FusedIterator for UnsafeIter < ' _ , T > { }
2776+
2777+ impl < T > fmt:: Debug for UnsafeIter < ' _ , T >
2778+ where
2779+ T : fmt:: Debug ,
2780+ {
2781+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2782+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
26382783 }
26392784}
26402785
@@ -2888,6 +3033,19 @@ where
28883033{
28893034 inner : RawIntoIter < T , A > ,
28903035}
3036+ impl < T , A > IntoIter < T , A >
3037+ where
3038+ A : Allocator ,
3039+ {
3040+ /// Returns a iterator of references over the remaining items.
3041+ #[ cfg_attr( feature = "inline-more" , inline) ]
3042+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3043+ Iter {
3044+ inner : self . inner . iter ( ) ,
3045+ marker : PhantomData ,
3046+ }
3047+ }
3048+ }
28913049
28923050impl < T , A : Allocator > Default for IntoIter < T , A > {
28933051 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2938,12 +3096,7 @@ where
29383096 A : Allocator ,
29393097{
29403098 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2941- f. debug_list ( )
2942- . entries ( Iter {
2943- inner : self . inner . iter ( ) ,
2944- marker : PhantomData ,
2945- } )
2946- . finish ( )
3099+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29473100 }
29483101}
29493102
@@ -2957,6 +3110,16 @@ where
29573110pub struct Drain < ' a , T , A : Allocator = Global > {
29583111 inner : RawDrain < ' a , T , A > ,
29593112}
3113+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3114+ /// Returns a iterator of references over the remaining items.
3115+ #[ cfg_attr( feature = "inline-more" , inline) ]
3116+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3117+ Iter {
3118+ inner : self . inner . iter ( ) ,
3119+ marker : PhantomData ,
3120+ }
3121+ }
3122+ }
29603123
29613124impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
29623125 type Item = T ;
@@ -2988,12 +3151,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29883151
29893152impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29903153 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2991- f. debug_list ( )
2992- . entries ( Iter {
2993- inner : self . inner . iter ( ) ,
2994- marker : PhantomData ,
2995- } )
2996- . finish ( )
3154+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29973155 }
29983156}
29993157
0 commit comments