@@ -1318,7 +1318,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13181318 } ) ;
13191319 }
13201320 Ordering :: Less =>
1321- // Safety : we know our other_key's ordering is less than self_key,
1321+ // SAFETY : we know our other_key's ordering is less than self_key,
13221322 // so inserting before will guarantee sorted order
13231323 unsafe {
13241324 self_cursor. insert_before_unchecked ( first_other_key, first_other_val) ;
@@ -1328,61 +1328,45 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13281328 }
13291329 }
13301330 } else {
1331- // Safety: if we reach here, that means our cursor has reached
1332- // the end of self BTreeMap, (other_key is greater than all the
1333- // previous self BTreeMap keys) so we just insert other_key here
1334- // at the end of the CursorMut
1331+ // SAFETY: reaching here means our cursor is at the end
1332+ // self BTreeMap so we just insert other_key here
13351333 unsafe {
13361334 self_cursor. insert_after_unchecked ( first_other_key, first_other_val) ;
13371335 }
13381336 }
13391337
13401338 for ( other_key, other_val) in other_iter {
1341- if self_cursor. peek_next ( ) . is_some ( ) {
1342- loop {
1343- let self_entry = self_cursor. peek_next ( ) ;
1344- if let Some ( ( self_key, _) ) = self_entry {
1345- match K :: cmp ( & other_key, self_key) {
1346- Ordering :: Equal => {
1347- self_cursor. with_next ( |self_key, self_val| {
1348- conflict ( self_key, self_val, other_val)
1349- } ) ;
1350- break ;
1351- }
1352- Ordering :: Less => {
1353- // Safety: we know our other_key's ordering is less than self_key,
1354- // so inserting before will guarantee sorted order
1355- unsafe {
1356- self_cursor. insert_before_unchecked ( other_key, other_val) ;
1357- }
1358- break ;
1359- }
1360- Ordering :: Greater => {
1361- // advance the cursor forward
1362- self_cursor. next ( ) ;
1339+ loop {
1340+ if let Some ( ( self_key, _) ) = self_cursor. peek_next ( ) {
1341+ match K :: cmp ( & other_key, self_key) {
1342+ Ordering :: Equal => {
1343+ self_cursor. with_next ( |self_key, self_val| {
1344+ conflict ( self_key, self_val, other_val)
1345+ } ) ;
1346+ break ;
1347+ }
1348+ Ordering :: Less => {
1349+ // SAFETY: we know our other_key's ordering is less than self_key,
1350+ // so inserting before will guarantee sorted order
1351+ unsafe {
1352+ self_cursor. insert_before_unchecked ( other_key, other_val) ;
13631353 }
1354+ break ;
13641355 }
1365- } else {
1366- // Safety: if we reach here, that means our cursor has reached
1367- // the end of self BTreeMap, (other_key is greater than all the
1368- // previous self BTreeMap keys) so we just insert other_key here
1369- // at the end of the Cursor
1370- unsafe {
1371- self_cursor. insert_after_unchecked ( other_key, other_val) ;
1356+ Ordering :: Greater => {
1357+ // advance the cursor forward
1358+ self_cursor. next ( ) ;
13721359 }
1373- self_cursor. next ( ) ;
1374- break ;
13751360 }
1361+ } else {
1362+ // SAFETY: reaching here means our cursor is at the end
1363+ // self BTreeMap so we just insert other_key here
1364+ unsafe {
1365+ self_cursor. insert_after_unchecked ( other_key, other_val) ;
1366+ }
1367+ self_cursor. next ( ) ;
1368+ break ;
13761369 }
1377- } else {
1378- // Safety: if we reach here, that means our cursor has reached
1379- // the end of self BTreeMap, (other_key is greater than all the
1380- // previous self BTreeMap keys) so we just insert the rest of
1381- // other_keys here at the end of CursorMut
1382- unsafe {
1383- self_cursor. insert_after_unchecked ( other_key, other_val) ;
1384- }
1385- self_cursor. next ( ) ;
13861370 }
13871371 }
13881372 }
@@ -3416,91 +3400,27 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
34163400 ///
34173401 /// If the cursor is at the end of the map then the function is not called
34183402 /// and this essentially does not do anything.
3403+ ///
3404+ /// # Safety
3405+ ///
3406+ /// You must ensure that the `BTreeMap` invariants are maintained.
3407+ /// Specifically:
3408+ ///
3409+ /// * The next element's key must be unique in the tree.
3410+ /// * All keys in the tree must remain in sorted order.
34193411 #[ allow( dead_code) ] /* This function exists for consistency with CursorMut */
34203412 pub ( super ) fn with_next ( & mut self , f : impl FnOnce ( K , V ) -> ( K , V ) ) {
3421- /// Call `f` with the next entry's key and value, replacing the
3422- /// next entry's key and value with the returned key and value.
3423- /// if `f` unwinds, the next entry is removed.
3424- /// Equivalent to a more efficient version of:
3425- /// ```ignore (this is an example equivalent)
3426- /// if let Some((k, v)) = self.remove_next() {
3427- /// let (k, v) = f(k, v);
3428- /// // Safety: key is unmodified
3429- /// unsafe { self.insert_after_unchecked(k, v) };
3430- /// }
3431- /// ```
3432- struct RemoveNextOnDrop < ' a , ' b , K , V , A = Global >
3433- where
3434- K : Ord ,
3435- A : Allocator + Clone ,
3436- {
3437- cursor : & ' a mut CursorMutKey < ' b , K , V , A > ,
3438- forget_next : bool ,
3439- }
3440-
3441- impl < K : Ord , V , A : Allocator + Clone > Drop for RemoveNextOnDrop < ' _ , ' _ , K , V , A > {
3442- fn drop ( & mut self ) {
3443- if self . forget_next {
3444- // Removes the next entry of the Cursor without running
3445- // running the destructor on the key and value (prevents double
3446- // free)
3447- self . cursor . forget_next_key_and_value ( ) ;
3448- }
3449- }
3450- }
3451-
3452- let mut remove_next_on_drop = RemoveNextOnDrop {
3453- cursor : self ,
3454- forget_next : false , // next value is not known yet
3455- } ;
3456-
3457- if let Some ( ( k_mut, v_mut) ) = remove_next_on_drop. cursor . peek_next ( ) {
3458- remove_next_on_drop. forget_next = true ;
3459- // Safety: we move the K, V out of the next entry,
3460- // we marked the entry's value to be forgotten
3461- // when remove_next_on_drop is dropped that
3462- // way we avoid returning to the caller leaving
3463- // a moved-out invalid value if `f` unwinds.
3464- let k = unsafe { ptr:: read ( k_mut) } ;
3465- let v = unsafe { ptr:: read ( v_mut) } ;
3413+ // if `f` unwinds, the next entry is already removed leaving
3414+ // the tree in valid state.
3415+ // FIXME: Once `MaybeDangling` is implemented, we can optimize
3416+ // this through using a drop handler and transmutating CursorMutKey<K, V>
3417+ // to CursorMutKey<ManuallyDrop<K>, ManuallyDrop<V>> (see PR #152418)
3418+ if let Some ( ( k, v) ) = self . remove_next ( ) {
3419+ // SAFETY: we remove the K, V out of the next entry,
3420+ // apply 'f' to get a new (K, V), and insert it back
3421+ // into the next entry that the cursor is pointing at
34663422 let ( k, v) = f ( k, v) ;
3467- unsafe { ptr:: write ( k_mut, k) } ;
3468- unsafe { ptr:: write ( v_mut, v) } ;
3469-
3470- remove_next_on_drop. forget_next = false ;
3471- }
3472- }
3473-
3474- /// Forgets the next element's key and value from the `BTreeMap`.
3475- ///
3476- /// The element's key and value does not run its destructor. The cursor position is
3477- /// unchanged (before the forgotten element).
3478- fn forget_next_key_and_value ( & mut self ) {
3479- let current = match self . current . take ( ) {
3480- Some ( current) => current,
3481- None => return ,
3482- } ;
3483-
3484- if current. reborrow ( ) . next_kv ( ) . is_err ( ) {
3485- self . current = Some ( current) ;
3486- return ;
3487- }
3488-
3489- let mut emptied_internal_root = false ;
3490- if let Ok ( next_kv) = current. next_kv ( ) {
3491- let ( ( key, val) , pos) =
3492- next_kv. remove_kv_tracking ( || emptied_internal_root = true , self . alloc . clone ( ) ) ;
3493- // Don't run destructor on next element's key and value
3494- mem:: forget ( key) ;
3495- mem:: forget ( val) ;
3496- self . current = Some ( pos) ;
3497- * self . length -= 1 ;
3498- if emptied_internal_root {
3499- // SAFETY: This is safe since current does not point within the now
3500- // empty root node.
3501- let root = unsafe { self . root . reborrow ( ) . as_mut ( ) . unwrap ( ) } ;
3502- root. pop_internal_level ( self . alloc . clone ( ) ) ;
3503- }
3423+ unsafe { self . insert_after_unchecked ( k, v) } ;
35043424 }
35053425 }
35063426
@@ -3717,85 +3637,17 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> {
37173637 /// If the cursor is at the end of the map then the function is not called
37183638 /// and this essentially does not do anything.
37193639 pub ( super ) fn with_next ( & mut self , f : impl FnOnce ( & K , V ) -> V ) {
3720- /// Call `f` with the next entry's key and value, replacing the
3721- /// next entry's value with the returned value. if `f` unwinds,
3722- /// the next entry is removed.
3723- /// Equivalent to a more efficient version of:
3724- /// ```ignore (this is an example equivalent)
3725- /// if let Some((k, v)) = self.remove_next() {
3726- /// let v = f(&k, v);
3727- /// // Safety: key is unmodified
3728- /// unsafe { self.insert_after_unchecked(k, v) };
3729- /// }
3730- /// ```
3731- struct RemoveNextOnDrop < ' a , ' b , K , V , A = Global >
3732- where
3733- K : Ord ,
3734- A : Allocator + Clone ,
3735- {
3736- cursor : & ' a mut CursorMut < ' b , K , V , A > ,
3737- forget_next : bool ,
3738- }
3739-
3740- impl < K : Ord , V , A : Allocator + Clone > Drop for RemoveNextOnDrop < ' _ , ' _ , K , V , A > {
3741- fn drop ( & mut self ) {
3742- if self . forget_next {
3743- // Removes the next entry of the Cursor without running
3744- // running the destructor on the value (prevents double
3745- // free)
3746- self . cursor . forget_next_value ( ) ;
3747- }
3748- }
3749- }
3750-
3751- let mut remove_next_on_drop = RemoveNextOnDrop {
3752- cursor : self ,
3753- forget_next : false , // next value is not known yet
3754- } ;
3755-
3756- if let Some ( ( k, v_mut) ) = remove_next_on_drop. cursor . peek_next ( ) {
3757- remove_next_on_drop. forget_next = true ;
3758- // Safety: we move the V out of the next entry,
3759- // we marked the entry's value to be forgotten
3760- // when remove_next_on_drop is dropped that
3761- // way we avoid returning to the caller leaving
3762- // a moved-out invalid value if `f` unwinds.
3763- let v = unsafe { ptr:: read ( v_mut) } ;
3764- let v = f ( k, v) ;
3765- unsafe { ptr:: write ( v_mut, v) } ;
3766- remove_next_on_drop. forget_next = false ;
3767- }
3768- }
3769-
3770- /// Forgets the next element's value from the `BTreeMap`.
3771- ///
3772- /// The element's value does not run its destructor. The cursor position is
3773- /// unchanged (before the forgotten element).
3774- fn forget_next_value ( & mut self ) {
3775- let current = match self . inner . current . take ( ) {
3776- Some ( current) => current,
3777- None => return ,
3778- } ;
3779-
3780- if current. reborrow ( ) . next_kv ( ) . is_err ( ) {
3781- self . inner . current = Some ( current) ;
3782- return ;
3783- }
3784-
3785- let mut emptied_internal_root = false ;
3786- if let Ok ( next_kv) = current. next_kv ( ) {
3787- let ( ( _, val) , pos) = next_kv
3788- . remove_kv_tracking ( || emptied_internal_root = true , self . inner . alloc . clone ( ) ) ;
3789- // Don't run destructor on next element's value
3790- mem:: forget ( val) ;
3791- self . inner . current = Some ( pos) ;
3792- * self . inner . length -= 1 ;
3793- if emptied_internal_root {
3794- // SAFETY: This is safe since current does not point within the now
3795- // empty root node.
3796- let root = unsafe { self . inner . root . reborrow ( ) . as_mut ( ) . unwrap ( ) } ;
3797- root. pop_internal_level ( self . inner . alloc . clone ( ) ) ;
3798- }
3640+ // if `f` unwinds, the next entry is already removed leaving
3641+ // the tree in valid state.
3642+ // FIXME: Once `MaybeDangling` is implemented, we can optimize
3643+ // this through using a drop handler and transmutating CursorMut<K, V>
3644+ // to CursorMut<K, ManuallyDrop<V>> (see PR #152418)
3645+ if let Some ( ( k, v) ) = self . remove_next ( ) {
3646+ // SAFETY: we remove the K, V out of the next entry,
3647+ // apply 'f' to get a new (K, V), and insert it back
3648+ // into the next entry that the cursor is pointing at
3649+ let v = f ( & k, v) ;
3650+ unsafe { self . insert_after_unchecked ( k, v) } ;
37993651 }
38003652 }
38013653
0 commit comments