@@ -1306,29 +1306,25 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13061306 let mut other_iter = other. into_iter ( ) ;
13071307 let ( first_other_key, first_other_val) = other_iter. next ( ) . unwrap ( ) ;
13081308
1309- // find the first gap that has the smallest key greater than the first key from other
1309+ // find the first gap that has the smallest key greater than or equal to
1310+ // the first key from other
13101311 let mut self_cursor = self . lower_bound_mut ( Bound :: Included ( & first_other_key) ) ;
13111312
1312- if let Some ( ( self_key, self_val ) ) = self_cursor. peek_next ( ) {
1313+ if let Some ( ( self_key, _ ) ) = self_cursor. peek_next ( ) {
13131314 match K :: cmp ( & first_other_key, self_key) {
13141315 Ordering :: Equal => {
1315- // SAFETY: We read in self_val's and hand it over to our conflict function
1316- // which will always return a value that we can use to overwrite what's
1317- // in self_val
1318- unsafe {
1319- let val = ptr:: read ( self_val) ;
1320- let next_val = ( conflict) ( self_key, val, first_other_val) ;
1321- ptr:: write ( self_val, next_val) ;
1322- }
1316+ self_cursor. with_next ( |self_key, self_val| {
1317+ conflict ( self_key, self_val, first_other_val)
1318+ } ) ;
13231319 }
13241320 Ordering :: Less =>
1325- // 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,
13261322 // so inserting before will guarantee sorted order
13271323 unsafe {
13281324 self_cursor. insert_before_unchecked ( first_other_key, first_other_val) ;
13291325 } ,
13301326 Ordering :: Greater => {
1331- unreachable ! ( "cursor 's peek_next would return None in this case " ) ;
1327+ unreachable ! ( "Cursor 's peek_next should return None. " ) ;
13321328 }
13331329 }
13341330 } else {
@@ -1345,33 +1341,29 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13451341 if self_cursor. peek_next ( ) . is_some ( ) {
13461342 loop {
13471343 let self_entry = self_cursor. peek_next ( ) ;
1348- if let Some ( ( self_key, self_val ) ) = self_entry {
1344+ if let Some ( ( self_key, _ ) ) = self_entry {
13491345 match K :: cmp ( & other_key, self_key) {
13501346 Ordering :: Equal => {
1351- // SAFETY: We read in self_val's and hand it over to our conflict function
1352- // which will always return a value that we can use to overwrite what's
1353- // in self_val
1354- unsafe {
1355- let val = ptr:: read ( self_val) ;
1356- let next_val = ( conflict) ( self_key, val, other_val) ;
1357- ptr:: write ( self_val, next_val) ;
1358- }
1347+ self_cursor. with_next ( |self_key, self_val| {
1348+ conflict ( self_key, self_val, other_val)
1349+ } ) ;
13591350 break ;
13601351 }
13611352 Ordering :: Less => {
1362- // SAFETY : we know our other_key's ordering is less than self_key,
1353+ // Safety : we know our other_key's ordering is less than self_key,
13631354 // so inserting before will guarantee sorted order
13641355 unsafe {
13651356 self_cursor. insert_before_unchecked ( other_key, other_val) ;
13661357 }
13671358 break ;
13681359 }
13691360 Ordering :: Greater => {
1361+ // advance the cursor forward
13701362 self_cursor. next ( ) ;
13711363 }
13721364 }
13731365 } else {
1374- // SAFETY : if we reach here, that means our cursor has reached
1366+ // Safety : if we reach here, that means our cursor has reached
13751367 // the end of self BTreeMap, (other_key is greater than all the
13761368 // previous self BTreeMap keys) so we just insert other_key here
13771369 // at the end of the Cursor
@@ -1383,7 +1375,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13831375 }
13841376 }
13851377 } else {
1386- // SAFETY : if we reach here, that means our cursor has reached
1378+ // Safety : if we reach here, that means our cursor has reached
13871379 // the end of self BTreeMap, (other_key is greater than all the
13881380 // previous self BTreeMap keys) so we just insert the rest of
13891381 // other_keys here at the end of CursorMut
@@ -3417,6 +3409,100 @@ impl<'a, K, V, A> CursorMutKey<'a, K, V, A> {
34173409
34183410// Now the tree editing operations
34193411impl < ' a , K : Ord , V , A : Allocator + Clone > CursorMutKey < ' a , K , V , A > {
3412+ /// Calls a function with ownership of the next element's key and
3413+ /// and value and expects it to return a value to write
3414+ /// back to the next element's key and value. The cursor is not
3415+ /// advanced forward.
3416+ ///
3417+ /// If the cursor is at the end of the map then the function is not called
3418+ /// and this essentially does not do anything.
3419+ #[ allow( dead_code) ] /* This function exists for consistency with CursorMut */
3420+ 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) } ;
3466+ 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 ( ( _, val) , pos) =
3492+ next_kv. remove_kv_tracking ( || emptied_internal_root = true , self . alloc . clone ( ) ) ;
3493+ // Don't run destructor on next element's value
3494+ mem:: forget ( val) ;
3495+ self . current = Some ( pos) ;
3496+ * self . length -= 1 ;
3497+ if emptied_internal_root {
3498+ // SAFETY: This is safe since current does not point within the now
3499+ // empty root node.
3500+ let root = unsafe { self . root . reborrow ( ) . as_mut ( ) . unwrap ( ) } ;
3501+ root. pop_internal_level ( self . alloc . clone ( ) ) ;
3502+ }
3503+ }
3504+ }
3505+
34203506 /// Inserts a new key-value pair into the map in the gap that the
34213507 /// cursor is currently pointing to.
34223508 ///
@@ -3622,6 +3708,96 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
36223708}
36233709
36243710impl < ' a , K : Ord , V , A : Allocator + Clone > CursorMut < ' a , K , V , A > {
3711+ /// Calls a function with a reference to the next element's key and
3712+ /// ownership of its value. The function is expected to return a value
3713+ /// to write back to the next element's value. The cursor is not
3714+ /// advanced forward.
3715+ ///
3716+ /// If the cursor is at the end of the map then the function is not called
3717+ /// and this essentially does not do anything.
3718+ pub ( super ) fn with_next ( & mut self , f : impl FnOnce ( & K , V ) -> V ) {
3719+ /// Call `f` with the next entry's key and value, replacing the
3720+ /// next entry's value with the returned value. if `f` unwinds,
3721+ /// the next entry is removed.
3722+ /// Equivalent to a more efficient version of:
3723+ /// ```ignore (this is an example equivalent)
3724+ /// if let Some((k, v)) = self.remove_next() {
3725+ /// let v = f(&k, v);
3726+ /// // Safety: key is unmodified
3727+ /// unsafe { self.insert_after_unchecked(k, v) };
3728+ /// }
3729+ /// ```
3730+ struct RemoveNextOnDrop < ' a , ' b , K , V , A = Global >
3731+ where
3732+ K : Ord ,
3733+ A : Allocator + Clone ,
3734+ {
3735+ cursor : & ' a mut CursorMut < ' b , K , V , A > ,
3736+ forget_next : bool ,
3737+ }
3738+
3739+ impl < K : Ord , V , A : Allocator + Clone > Drop for RemoveNextOnDrop < ' _ , ' _ , K , V , A > {
3740+ fn drop ( & mut self ) {
3741+ if self . forget_next {
3742+ // Removes the next entry of the Cursor without running
3743+ // running the destructor on the value (prevents double
3744+ // free)
3745+ self . cursor . forget_next_value ( ) ;
3746+ }
3747+ }
3748+ }
3749+
3750+ let mut remove_next_on_drop = RemoveNextOnDrop {
3751+ cursor : self ,
3752+ forget_next : false , // next value is not known yet
3753+ } ;
3754+
3755+ if let Some ( ( k, v_mut) ) = remove_next_on_drop. cursor . peek_next ( ) {
3756+ remove_next_on_drop. forget_next = true ;
3757+ // Safety: we move the V out of the next entry,
3758+ // we marked the entry's value to be forgotten
3759+ // when remove_next_on_drop is dropped that
3760+ // way we avoid returning to the caller leaving
3761+ // a moved-out invalid value if `f` unwinds.
3762+ let v = unsafe { ptr:: read ( v_mut) } ;
3763+ let v = f ( k, v) ;
3764+ unsafe { ptr:: write ( v_mut, v) } ;
3765+ remove_next_on_drop. forget_next = false ;
3766+ }
3767+ }
3768+
3769+ /// Forgets the next element's value from the `BTreeMap`.
3770+ ///
3771+ /// The element's value does not run its destructor. The cursor position is
3772+ /// unchanged (before the forgotten element).
3773+ fn forget_next_value ( & mut self ) {
3774+ let current = match self . inner . current . take ( ) {
3775+ Some ( current) => current,
3776+ None => return ,
3777+ } ;
3778+
3779+ if current. reborrow ( ) . next_kv ( ) . is_err ( ) {
3780+ self . inner . current = Some ( current) ;
3781+ return ;
3782+ }
3783+
3784+ let mut emptied_internal_root = false ;
3785+ if let Ok ( next_kv) = current. next_kv ( ) {
3786+ let ( ( _, val) , pos) = next_kv
3787+ . remove_kv_tracking ( || emptied_internal_root = true , self . inner . alloc . clone ( ) ) ;
3788+ // Don't run destructor on next element's value
3789+ mem:: forget ( val) ;
3790+ self . inner . current = Some ( pos) ;
3791+ * self . inner . length -= 1 ;
3792+ if emptied_internal_root {
3793+ // SAFETY: This is safe since current does not point within the now
3794+ // empty root node.
3795+ let root = unsafe { self . inner . root . reborrow ( ) . as_mut ( ) . unwrap ( ) } ;
3796+ root. pop_internal_level ( self . inner . alloc . clone ( ) ) ;
3797+ }
3798+ }
3799+ }
3800+
36253801 /// Inserts a new key-value pair into the map in the gap that the
36263802 /// cursor is currently pointing to.
36273803 ///
0 commit comments