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
@@ -2508,6 +2531,16 @@ pub struct IterMut<'a, T> {
25082531 inner : RawIter < T > ,
25092532 marker : PhantomData < & ' a mut T > ,
25102533}
2534+ impl < ' a , T > IterMut < ' a , T > {
2535+ /// Returns a iterator of references over the remaining items.
2536+ #[ cfg_attr( feature = "inline-more" , inline) ]
2537+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2538+ Iter {
2539+ inner : self . inner . clone ( ) ,
2540+ marker : PhantomData ,
2541+ }
2542+ }
2543+ }
25112544
25122545impl < T > Default for IterMut < ' _ , T > {
25132546 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2556,12 +2589,124 @@ where
25562589 T : fmt:: Debug ,
25572590{
25582591 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2559- f. debug_list ( )
2560- . entries ( Iter {
2561- inner : self . inner . clone ( ) ,
2562- marker : PhantomData ,
2563- } )
2564- . finish ( )
2592+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2593+ }
2594+ }
2595+
2596+ /// An unsafe iterator over the entries of a `HashTable` in arbitrary order.
2597+ /// The iterator element type is `NonNull<T>`.
2598+ ///
2599+ /// This `struct` is created by the [`unsafe_iter`] method on [`HashTable`].
2600+ ///
2601+ /// This is used for implementations of iterators with "mixed" mutability on
2602+ /// the iterated elements. For example, a mutable iterator for a map may return
2603+ /// an immutable key alongside a mutable value, even though these are both
2604+ /// stored inside the table.
2605+ ///
2606+ /// If you have no idea what any of this means, you probably should be using
2607+ /// [`IterMut`] instead, as it does not have any safety requirements.
2608+ ///
2609+ /// # Safety
2610+ ///
2611+ /// In order to correctly use this iterator, it should be wrapped in a safe
2612+ /// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2613+ /// correct [variance].
2614+ ///
2615+ /// For example, below is a simplified [`hash_map::IterMut`] implementation
2616+ /// that correctly returns a [covariant] key, and an [invariant] value:
2617+ ///
2618+ /// [variance]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance
2619+ /// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
2620+ /// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
2621+ /// [`hash_map::IterMut`]: crate::hash_map::IterMut
2622+ ///
2623+ /// ```rust
2624+ /// use core::marker::PhantomData;
2625+ /// use hashbrown::hash_table;
2626+ ///
2627+ /// pub struct IterMut<'a, K, V> {
2628+ /// inner: hash_table::UnsafeIter<'a, (K, V)>,
2629+ /// // Covariant over keys, invariant over values
2630+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2631+ /// }
2632+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2633+ /// // Immutable keys, mutable values
2634+ /// type Item = (&'a K, &'a mut V);
2635+ ///
2636+ /// fn next(&mut self) -> Option<Self::Item> {
2637+ /// // SAFETY: The lifetime of the dereferenced pointer is derived from
2638+ /// // the lifetime of its iterator, ensuring that it's always valid.
2639+ /// // Additionally, we match the mutability in `self.marker` to ensure
2640+ /// // the correct variance.
2641+ /// let (ref key, ref mut val) = unsafe { *self.inner.next() }?;
2642+ /// Some((key, val))
2643+ /// }
2644+ /// }
2645+ /// ```
2646+ pub struct UnsafeIter < ' a , T > {
2647+ inner : RawIter < T > ,
2648+ marker : PhantomData < & ' a ( ) > ,
2649+ }
2650+ impl < ' a , T > UnsafeIter < ' a , T > {
2651+ /// Returns a iterator of references over the remaining items.
2652+ #[ cfg_attr( feature = "inline-more" , inline) ]
2653+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2654+ Iter {
2655+ inner : self . inner . clone ( ) ,
2656+ marker : PhantomData ,
2657+ }
2658+ }
2659+ }
2660+
2661+ impl < T > Default for UnsafeIter < ' _ , T > {
2662+ #[ cfg_attr( feature = "inline-more" , inline) ]
2663+ fn default ( ) -> Self {
2664+ UnsafeIter {
2665+ inner : Default :: default ( ) ,
2666+ marker : PhantomData ,
2667+ }
2668+ }
2669+ }
2670+ impl < ' a , T > Iterator for UnsafeIter < ' a , T > {
2671+ type Item = NonNull < T > ;
2672+
2673+ fn next ( & mut self ) -> Option < Self :: Item > {
2674+ // Avoid `Option::map` because it bloats LLVM IR.
2675+ match self . inner . next ( ) {
2676+ Some ( bucket) => Some ( unsafe { NonNull :: new_unchecked ( bucket. as_ptr ( ) ) } ) ,
2677+ None => None ,
2678+ }
2679+ }
2680+
2681+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2682+ self . inner . size_hint ( )
2683+ }
2684+
2685+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2686+ where
2687+ Self : Sized ,
2688+ F : FnMut ( B , Self :: Item ) -> B ,
2689+ {
2690+ self . inner . fold ( init, |acc, bucket| unsafe {
2691+ f ( acc, NonNull :: new_unchecked ( bucket. as_ptr ( ) ) )
2692+ } )
2693+ }
2694+ }
2695+
2696+ impl < T > ExactSizeIterator for UnsafeIter < ' _ , T > {
2697+ fn len ( & self ) -> usize {
2698+ self . inner . len ( )
2699+ }
2700+ }
2701+
2702+ impl < T > FusedIterator for UnsafeIter < ' _ , T > { }
2703+
2704+ impl < T > fmt:: Debug for UnsafeIter < ' _ , T >
2705+ where
2706+ T : fmt:: Debug ,
2707+ {
2708+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2709+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
25652710 }
25662711}
25672712
@@ -2815,6 +2960,19 @@ where
28152960{
28162961 inner : RawIntoIter < T , A > ,
28172962}
2963+ impl < T , A > IntoIter < T , A >
2964+ where
2965+ A : Allocator ,
2966+ {
2967+ /// Returns a iterator of references over the remaining items.
2968+ #[ cfg_attr( feature = "inline-more" , inline) ]
2969+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2970+ Iter {
2971+ inner : self . inner . iter ( ) ,
2972+ marker : PhantomData ,
2973+ }
2974+ }
2975+ }
28182976
28192977impl < T , A : Allocator > Default for IntoIter < T , A > {
28202978 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2865,12 +3023,7 @@ where
28653023 A : Allocator ,
28663024{
28673025 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2868- f. debug_list ( )
2869- . entries ( Iter {
2870- inner : self . inner . iter ( ) ,
2871- marker : PhantomData ,
2872- } )
2873- . finish ( )
3026+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
28743027 }
28753028}
28763029
@@ -2884,6 +3037,16 @@ where
28843037pub struct Drain < ' a , T , A : Allocator = Global > {
28853038 inner : RawDrain < ' a , T , A > ,
28863039}
3040+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3041+ /// Returns a iterator of references over the remaining items.
3042+ #[ cfg_attr( feature = "inline-more" , inline) ]
3043+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3044+ Iter {
3045+ inner : self . inner . iter ( ) ,
3046+ marker : PhantomData ,
3047+ }
3048+ }
3049+ }
28873050
28883051impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
28893052 type Item = T ;
@@ -2915,12 +3078,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29153078
29163079impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29173080 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2918- f. debug_list ( )
2919- . entries ( Iter {
2920- inner : self . inner . iter ( ) ,
2921- marker : PhantomData ,
2922- } )
2923- . finish ( )
3081+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29243082 }
29253083}
29263084
0 commit comments