144144#![ stable( feature = "rust1" , since = "1.0.0" ) ]
145145
146146use core:: fmt;
147- use core:: iter:: { FromIterator , FusedIterator , InPlaceIterable , SourceIter , TrustedLen } ;
147+ use core:: iter:: { FromIterator , FusedIterator , InPlaceIterable , Rev , SourceIter , TrustedLen } ;
148148use core:: mem:: { self , swap, ManuallyDrop } ;
149149use core:: ops:: { Deref , DerefMut } ;
150150use core:: ptr;
@@ -153,6 +153,7 @@ use crate::collections::TryReserveError;
153153use crate :: slice;
154154use crate :: vec:: { self , AsVecIntoIter , Vec } ;
155155
156+ use super :: btree:: borrow:: DormantMutRef ;
156157use super :: SpecExtend ;
157158
158159#[ cfg( test) ]
@@ -819,6 +820,33 @@ impl<T: Ord> BinaryHeap<T> {
819820 // data[0..first_removed] is untouched, so we only need to rebuild the tail:
820821 self . rebuild_tail ( first_removed) ;
821822 }
823+
824+ /// Returns a mutable iterator visiting all values in the underlying vector, in
825+ /// arbitrary order. When `IterMut` is dropped, the binary heap is rebuilt.
826+ ///
827+ /// Note: If the `IterMut` value is leaked, the heap may be in an
828+ /// inconsistent state.
829+ ///
830+ /// # Examples
831+ ///
832+ /// Basic usage:
833+ ///
834+ /// ```
835+ /// #![feature(binary_heap_iter_mut)]
836+ /// use std::collections::BinaryHeap;
837+ ///
838+ /// let mut heap = BinaryHeap::from([-10, -5, 1, 2, 4, 13]);
839+ ///
840+ /// heap.iter_mut().for_each(|x| *x += 1);
841+ ///
842+ /// assert_eq!(vec![-9, -4, 2, 3, 5, 14], heap.into_sorted_vec());
843+ /// ```
844+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
845+ pub fn iter_mut ( & mut self ) -> IterMut < ' _ , T > {
846+ let ( this, dormant) = DormantMutRef :: new ( self ) ;
847+ let it = this. data . iter_mut ( ) . rev ( ) ; // reversed to take advantage of `rebuild_tail` on drop
848+ IterMut { iter_mut : ManuallyDrop :: new ( it) , heap : ManuallyDrop :: new ( dormant) }
849+ }
822850}
823851
824852impl < T > BinaryHeap < T > {
@@ -1357,6 +1385,65 @@ impl<T> ExactSizeIterator for Iter<'_, T> {
13571385#[ stable( feature = "fused" , since = "1.26.0" ) ]
13581386impl < T > FusedIterator for Iter < ' _ , T > { }
13591387
1388+ /// A mutable iterator over the elements of a `BinaryHeap`.
1389+ ///
1390+ /// This `struct` is created by [`BinaryHeap::iter_mut()`]. See its
1391+ /// documentation for more.
1392+ ///
1393+ /// [`iter_mut`]: BinaryHeap::iter_mut
1394+ #[ must_use = "iterators are lazy and do nothing unless consumed" ]
1395+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
1396+ pub struct IterMut < ' a , T : ' a + Ord > {
1397+ iter_mut : ManuallyDrop < Rev < slice:: IterMut < ' a , T > > > ,
1398+ heap : ManuallyDrop < DormantMutRef < ' a , BinaryHeap < T > > > ,
1399+ }
1400+
1401+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
1402+ impl < ' a , T : Ord > Iterator for IterMut < ' a , T > {
1403+ type Item = & ' a mut T ;
1404+
1405+ #[ inline]
1406+ fn next ( & mut self ) -> Option < & ' a mut T > {
1407+ self . iter_mut . next ( )
1408+ }
1409+
1410+ #[ inline]
1411+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1412+ self . iter_mut . size_hint ( )
1413+ }
1414+ }
1415+
1416+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
1417+ impl < T : fmt:: Debug + Ord > fmt:: Debug for IterMut < ' _ , T > {
1418+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1419+ f. debug_tuple ( "IterMut" ) . field ( & self . iter_mut ) . finish ( )
1420+ }
1421+ }
1422+
1423+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
1424+ impl < T : Ord > Drop for IterMut < ' _ , T > {
1425+ fn drop ( & mut self ) {
1426+ let remaining = self . iter_mut . len ( ) ;
1427+
1428+ // Early drop to avoid alias after recovering &mut BinaryHeap
1429+ // SAFETY: we're done using it.
1430+ unsafe { ManuallyDrop :: drop ( & mut self . iter_mut ) } ;
1431+
1432+ // SAFETY:
1433+ // take: `self.heap` is not used again.
1434+ // awaken: `self.iter_mut` has been dropped and hence no references to the heap remain.
1435+ let heap = unsafe { ManuallyDrop :: take ( & mut self . heap ) . awaken ( ) } ;
1436+ heap. rebuild_tail ( remaining) ;
1437+ }
1438+ }
1439+
1440+ #[ unstable( feature = "binary_heap_iter_mut" , issue = "98524" ) ]
1441+ impl < T : Ord > ExactSizeIterator for IterMut < ' _ , T > {
1442+ fn is_empty ( & self ) -> bool {
1443+ self . iter_mut . is_empty ( )
1444+ }
1445+ }
1446+
13601447/// An owning iterator over the elements of a `BinaryHeap`.
13611448///
13621449/// This `struct` is created by [`BinaryHeap::into_iter()`]
@@ -1653,6 +1740,16 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
16531740 }
16541741}
16551742
1743+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1744+ impl < ' a , T : Ord > IntoIterator for & ' a mut BinaryHeap < T > {
1745+ type Item = & ' a mut T ;
1746+ type IntoIter = IterMut < ' a , T > ;
1747+
1748+ fn into_iter ( self ) -> IterMut < ' a , T > {
1749+ self . iter_mut ( )
1750+ }
1751+ }
1752+
16561753#[ stable( feature = "rust1" , since = "1.0.0" ) ]
16571754impl < T : Ord > Extend < T > for BinaryHeap < T > {
16581755 #[ inline]
0 commit comments