144
144
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
145
145
146
146
use core:: fmt;
147
- use core:: iter:: { FromIterator , FusedIterator , InPlaceIterable , SourceIter , TrustedLen } ;
147
+ use core:: iter:: { FromIterator , FusedIterator , InPlaceIterable , Rev , SourceIter , TrustedLen } ;
148
148
use core:: mem:: { self , swap, ManuallyDrop } ;
149
149
use core:: ops:: { Deref , DerefMut } ;
150
150
use core:: ptr;
@@ -153,6 +153,7 @@ use crate::collections::TryReserveError;
153
153
use crate :: slice;
154
154
use crate :: vec:: { self , AsVecIntoIter , Vec } ;
155
155
156
+ use super :: btree:: borrow:: DormantMutRef ;
156
157
use super :: SpecExtend ;
157
158
158
159
#[ cfg( test) ]
@@ -819,6 +820,33 @@ impl<T: Ord> BinaryHeap<T> {
819
820
// data[0..first_removed] is untouched, so we only need to rebuild the tail:
820
821
self . rebuild_tail ( first_removed) ;
821
822
}
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
+ }
822
850
}
823
851
824
852
impl < T > BinaryHeap < T > {
@@ -1357,6 +1385,65 @@ impl<T> ExactSizeIterator for Iter<'_, T> {
1357
1385
#[ stable( feature = "fused" , since = "1.26.0" ) ]
1358
1386
impl < T > FusedIterator for Iter < ' _ , T > { }
1359
1387
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
+
1360
1447
/// An owning iterator over the elements of a `BinaryHeap`.
1361
1448
///
1362
1449
/// This `struct` is created by [`BinaryHeap::into_iter()`]
@@ -1653,6 +1740,16 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
1653
1740
}
1654
1741
}
1655
1742
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
+
1656
1753
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1657
1754
impl < T : Ord > Extend < T > for BinaryHeap < T > {
1658
1755
#[ inline]
0 commit comments