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,35 @@ 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+ ///
1091+ /// # Safety
1092+ ///
1093+ /// Any part of the returned elements which is mutated must be made invariant.
1094+ /// See the documentation for [`UnsafeIter`] for an example and further
1095+ /// explanation.
1096+ pub unsafe fn unsafe_iter ( & mut self ) -> UnsafeIter < ' _ , T > {
1097+ UnsafeIter {
1098+ inner : unsafe { self . raw . iter ( ) } ,
1099+ marker : PhantomData ,
1100+ }
1101+ }
1102+
10741103 /// An iterator producing the `usize` indices of all occupied buckets.
10751104 ///
10761105 /// The order in which the iterator yields indices is unspecified
@@ -2508,6 +2537,16 @@ pub struct IterMut<'a, T> {
25082537 inner : RawIter < T > ,
25092538 marker : PhantomData < & ' a mut T > ,
25102539}
2540+ impl < ' a , T > IterMut < ' a , T > {
2541+ /// Returns a iterator of references over the remaining items.
2542+ #[ cfg_attr( feature = "inline-more" , inline) ]
2543+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2544+ Iter {
2545+ inner : self . inner . clone ( ) ,
2546+ marker : PhantomData ,
2547+ }
2548+ }
2549+ }
25112550
25122551impl < T > Default for IterMut < ' _ , T > {
25132552 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2556,12 +2595,123 @@ where
25562595 T : fmt:: Debug ,
25572596{
25582597 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 ( )
2598+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
2599+ }
2600+ }
2601+
2602+ /// An unsafe iterator over the entries of a `HashTable` in arbitrary order.
2603+ /// The iterator element type is `NonNull<T>`.
2604+ ///
2605+ /// This `struct` is created by the [`unsafe_iter`] method on [`HashTable`].
2606+ ///
2607+ /// This is used for implementations of iterators with "mixed" mutability on
2608+ /// the iterated elements. For example, a mutable iterator for a map may return
2609+ /// an immutable key alongside a mutable value, even though these are both
2610+ /// stored inside the table.
2611+ ///
2612+ /// If you have no idea what any of this means, you probably should be using
2613+ /// [`IterMut`] instead, as it does not have any safety requirements.
2614+ ///
2615+ /// # Safety
2616+ ///
2617+ /// In order to correctly use this iterator, it should be wrapped in a safe
2618+ /// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2619+ /// correct [variance].
2620+ ///
2621+ /// For example, below is a simplified [`hash_map::IterMut`] implementation
2622+ /// that correctly returns a [covariant] key, and an [invariant] value:
2623+ ///
2624+ /// [variance]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance
2625+ /// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
2626+ /// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
2627+ /// [`hash_map::IterMut`]: crate::hash_map::IterMut
2628+ ///
2629+ /// ```rust
2630+ /// use core::marker::PhantomData;
2631+ /// use hashbrown::hash_table;
2632+ ///
2633+ /// pub struct IterMut<'a, K, V> {
2634+ /// inner: hash_table::UnsafeIter<'a, (K, V)>,
2635+ /// // Covariant over keys, invariant over values
2636+ /// marker: PhantomData<(&'a K, &'a mut V)>,
2637+ /// }
2638+ /// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2639+ /// // Immutable keys, mutable values
2640+ /// type Item = (&'a K, &'a mut V);
2641+ ///
2642+ /// fn next(&mut self) -> Option<Self::Item> {
2643+ /// // SAFETY: The lifetime of the dereferenced pointer is derived from
2644+ /// // the lifetime of its iterator, ensuring that it's always valid.
2645+ /// // Additionally, we match the mutability in `self.marker` to ensure
2646+ /// // the correct variance.
2647+ /// let (ref key, ref mut val) = unsafe { *self.inner.next() }?;
2648+ /// Some((key, val))
2649+ /// }
2650+ /// }
2651+ /// ```
2652+ pub struct UnsafeIter < ' a , T > {
2653+ inner : RawIter < T > ,
2654+ marker : PhantomData < & ' a ( ) > ,
2655+ }
2656+ impl < ' a , T > UnsafeIter < ' a , T > {
2657+ /// Returns a iterator of references over the remaining items.
2658+ #[ cfg_attr( feature = "inline-more" , inline) ]
2659+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2660+ Iter {
2661+ inner : self . inner . clone ( ) ,
2662+ marker : PhantomData ,
2663+ }
2664+ }
2665+ }
2666+
2667+ impl < T > Default for UnsafeIter < ' _ , T > {
2668+ #[ cfg_attr( feature = "inline-more" , inline) ]
2669+ fn default ( ) -> Self {
2670+ UnsafeIter {
2671+ inner : Default :: default ( ) ,
2672+ marker : PhantomData ,
2673+ }
2674+ }
2675+ }
2676+ impl < ' a , T > Iterator for UnsafeIter < ' a , T > {
2677+ type Item = NonNull < T > ;
2678+
2679+ fn next ( & mut self ) -> Option < Self :: Item > {
2680+ // Avoid `Option::map` because it bloats LLVM IR.
2681+ match self . inner . next ( ) {
2682+ Some ( bucket) => Some ( unsafe { NonNull :: new_unchecked ( bucket. as_ptr ( ) ) } ) ,
2683+ None => None ,
2684+ }
2685+ }
2686+
2687+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2688+ self . inner . size_hint ( )
2689+ }
2690+
2691+ fn fold < B , F > ( self , init : B , mut f : F ) -> B
2692+ where
2693+ Self : Sized ,
2694+ F : FnMut ( B , Self :: Item ) -> B ,
2695+ {
2696+ self . inner
2697+ . fold ( init, |acc, bucket| unsafe { f ( acc, NonNull :: new_unchecked ( bucket. as_ptr ( ) ) ) } )
2698+ }
2699+ }
2700+
2701+ impl < T > ExactSizeIterator for UnsafeIter < ' _ , T > {
2702+ fn len ( & self ) -> usize {
2703+ self . inner . len ( )
2704+ }
2705+ }
2706+
2707+ impl < T > FusedIterator for UnsafeIter < ' _ , T > { }
2708+
2709+ impl < T > fmt:: Debug for UnsafeIter < ' _ , T >
2710+ where
2711+ T : fmt:: Debug ,
2712+ {
2713+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2714+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
25652715 }
25662716}
25672717
@@ -2815,6 +2965,19 @@ where
28152965{
28162966 inner : RawIntoIter < T , A > ,
28172967}
2968+ impl < T , A > IntoIter < T , A >
2969+ where
2970+ A : Allocator ,
2971+ {
2972+ /// Returns a iterator of references over the remaining items.
2973+ #[ cfg_attr( feature = "inline-more" , inline) ]
2974+ pub fn iter ( & self ) -> Iter < ' _ , T > {
2975+ Iter {
2976+ inner : self . inner . iter ( ) ,
2977+ marker : PhantomData ,
2978+ }
2979+ }
2980+ }
28182981
28192982impl < T , A : Allocator > Default for IntoIter < T , A > {
28202983 #[ cfg_attr( feature = "inline-more" , inline) ]
@@ -2865,12 +3028,7 @@ where
28653028 A : Allocator ,
28663029{
28673030 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 ( )
3031+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
28743032 }
28753033}
28763034
@@ -2884,6 +3042,16 @@ where
28843042pub struct Drain < ' a , T , A : Allocator = Global > {
28853043 inner : RawDrain < ' a , T , A > ,
28863044}
3045+ impl < ' a , T , A : Allocator > Drain < ' a , T , A > {
3046+ /// Returns a iterator of references over the remaining items.
3047+ #[ cfg_attr( feature = "inline-more" , inline) ]
3048+ pub fn iter ( & self ) -> Iter < ' _ , T > {
3049+ Iter {
3050+ inner : self . inner . iter ( ) ,
3051+ marker : PhantomData ,
3052+ }
3053+ }
3054+ }
28873055
28883056impl < T , A : Allocator > Iterator for Drain < ' _ , T , A > {
28893057 type Item = T ;
@@ -2915,12 +3083,7 @@ impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
29153083
29163084impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for Drain < ' _ , T , A > {
29173085 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 ( )
3086+ f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
29243087 }
29253088}
29263089
0 commit comments