@@ -348,7 +348,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
348348
349349 loop {
350350 let result = stack. with ( move |pusher, node| {
351- // Same basic logic as found in `find `, but with PartialSearchStack mediating the
351+ // Same basic logic as found in `get `, but with PartialSearchStack mediating the
352352 // actual nodes for us
353353 match Node :: search ( node, & key) {
354354 Found ( mut handle) => {
@@ -438,14 +438,14 @@ impl<K: Ord, V> BTreeMap<K, V> {
438438 /// ```
439439 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
440440 pub fn remove < Q : ?Sized > ( & mut self , key : & Q ) -> Option < V > where K : Borrow < Q > , Q : Ord {
441- // See `swap ` for a more thorough description of the stuff going on in here
441+ // See `insert ` for a more thorough description of the stuff going on in here
442442 let mut stack = stack:: PartialSearchStack :: new ( self ) ;
443443 loop {
444444 let result = stack. with ( move |pusher, node| {
445445 match Node :: search ( node, key) {
446446 Found ( handle) => {
447447 // Perfect match. Terminate the stack here, and remove the entry
448- Finished ( Some ( pusher. seal ( handle) . remove ( ) ) )
448+ Finished ( Some ( pusher. seal ( handle) . remove ( ) . 1 ) )
449449 } ,
450450 GoDown ( handle) => {
451451 // We need to keep searching, try to go down the next edge
@@ -463,6 +463,131 @@ impl<K: Ord, V> BTreeMap<K, V> {
463463 }
464464 }
465465 }
466+
467+ /// Moves all elements from `other` into `Self`, leaving `other` empty.
468+ ///
469+ /// # Examples
470+ ///
471+ /// ```
472+ /// # #![feature(btree_append_split_off)]
473+ /// use std::collections::BTreeMap;
474+ ///
475+ /// let mut a = BTreeMap::new();
476+ /// a.insert(1, "a");
477+ /// a.insert(2, "b");
478+ /// a.insert(3, "c");
479+ ///
480+ /// let mut b = BTreeMap::new();
481+ /// b.insert(3, "d");
482+ /// b.insert(4, "e");
483+ /// b.insert(5, "f");
484+ ///
485+ /// a.append(&mut b);
486+ ///
487+ /// assert_eq!(a.len(), 5);
488+ /// assert_eq!(b.len(), 0);
489+ ///
490+ /// assert_eq!(a[&1], "a");
491+ /// assert_eq!(a[&2], "b");
492+ /// assert_eq!(a[&3], "d");
493+ /// assert_eq!(a[&4], "e");
494+ /// assert_eq!(a[&5], "f");
495+ /// ```
496+ #[ unstable( feature = "append" ,
497+ reason = "recently added as part of collections reform 2" ) ]
498+ pub fn append ( & mut self , other : & mut Self ) {
499+ let b = other. b ;
500+ for ( key, value) in mem:: replace ( other, BTreeMap :: with_b ( b) ) {
501+ self . insert ( key, value) ;
502+ }
503+ }
504+
505+ /// Splits the map into two at the given key,
506+ /// retaining the first half in-place and returning the second one.
507+ ///
508+ /// # Examples
509+ ///
510+ /// ```
511+ /// # #![feature(btree_append_split_off)]
512+ /// use std::collections::BTreeMap;
513+ ///
514+ /// a.insert(1, "a");
515+ /// a.insert(2, "b");
516+ /// a.insert(3, "c");
517+ /// a.insert(4, "d");
518+ /// a.insert(5, "e");
519+ ///
520+ /// let b = a.split_off(3);
521+ ///
522+ /// assert_eq!(a.len(), 2);
523+ /// assert_eq!(b.len(), 3);
524+ ///
525+ /// assert_eq!(a[&1], "a");
526+ /// assert_eq!(a[&2], "b");
527+ /// assert_eq!(b[&3], "c");
528+ /// assert_eq!(b[&4], "d");
529+ /// assert_eq!(b[&5], "e");
530+ /// ```
531+ #[ unstable( feature = "split_off" ,
532+ reason = "recently added as part of collections reform 2" ) ]
533+ pub fn split_off < Q : ?Sized > ( & mut self , at : & Q ) -> Self where K : Borrow < Q > , Q : Ord {
534+ let mut other = BTreeMap :: new ( ) ;
535+
536+ if self . len ( ) == 0 {
537+ return other;
538+ }
539+
540+ // FIXME(RFC #811) We can't check for `at` pointing before the
541+ // first element and then swap `self` and `other`, because
542+ // `self` will still be borrowed immutably.
543+ // `unwrap` won't panic because `self.len()` > 0.
544+ let should_swap = at <= self . keys ( ) . next ( ) . unwrap ( ) . borrow ( ) ;
545+
546+ // Does `at` point before the first element?
547+ if should_swap {
548+ mem:: swap ( self , & mut other) ;
549+ return other;
550+ }
551+ // Does `at` point behind the last element?
552+ // `unwrap` won't panic because `self.len()` > 0.
553+ else if at > self . keys ( ) . rev ( ) . next ( ) . unwrap ( ) . borrow ( ) {
554+ return other;
555+ }
556+
557+ let mut remove_greater_or_equal = || {
558+ let mut stack = stack:: PartialSearchStack :: new ( self ) ;
559+ loop {
560+ let result = stack. with ( move |pusher, node| {
561+ match Node :: greater_or_equal ( node, at) {
562+ Found ( handle) => {
563+ // Found a matching key. Terminate the stack here, and remove the entry
564+ Finished ( Some ( pusher. seal ( handle) . remove ( ) ) )
565+ } ,
566+ GoDown ( handle) => {
567+ // We need to keep searching, try to go down the next edge
568+ match handle. force ( ) {
569+ // We're at a leaf; no matching key found
570+ Leaf ( _) => Finished ( None ) ,
571+ Internal ( internal_handle) => Continue ( pusher. push ( internal_handle) )
572+ }
573+ }
574+ }
575+ } ) ;
576+ match result {
577+ Finished ( ret) => return ret,
578+ Continue ( new_stack) => stack = new_stack
579+ }
580+ }
581+ } ;
582+
583+ // Remove and move all elements greater than or equal to at
584+ loop {
585+ match remove_greater_or_equal ( ) {
586+ Some ( ( key, value) ) => other. insert ( key, value) ,
587+ None => return other,
588+ } ;
589+ }
590+ }
466591}
467592
468593#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -693,16 +818,16 @@ mod stack {
693818 impl < ' a , K , V > SearchStack < ' a , K , V , handle:: KV , handle:: Leaf > {
694819 /// Removes the key and value in the top element of the stack, then handles underflows as
695820 /// described in BTree's pop function.
696- fn remove_leaf ( mut self ) -> V {
821+ fn remove_leaf ( mut self ) -> ( K , V ) {
697822 self . map . length -= 1 ;
698823
699824 // Remove the key-value pair from the leaf that this search stack points to.
700825 // Then, note if the leaf is underfull, and promptly forget the leaf and its ptr
701826 // to avoid ownership issues.
702- let ( value, mut underflow) = unsafe {
703- let ( _ , value) = self . top . from_raw_mut ( ) . remove_as_leaf ( ) ;
827+ let ( key , value, mut underflow) = unsafe {
828+ let ( key , value) = self . top . from_raw_mut ( ) . remove_as_leaf ( ) ;
704829 let underflow = self . top . from_raw ( ) . node ( ) . is_underfull ( ) ;
705- ( value, underflow)
830+ ( key , value, underflow)
706831 } ;
707832
708833 loop {
@@ -717,7 +842,7 @@ mod stack {
717842 self . map . depth -= 1 ;
718843 self . map . root . hoist_lone_child ( ) ;
719844 }
720- return value;
845+ return ( key , value) ;
721846 }
722847 Some ( mut handle) => {
723848 if underflow {
@@ -728,7 +853,7 @@ mod stack {
728853 }
729854 } else {
730855 // All done!
731- return value;
856+ return ( key , value) ;
732857 }
733858 }
734859 }
@@ -739,7 +864,7 @@ mod stack {
739864 impl < ' a , K , V > SearchStack < ' a , K , V , handle:: KV , handle:: LeafOrInternal > {
740865 /// Removes the key and value in the top element of the stack, then handles underflows as
741866 /// described in BTree's pop function.
742- pub fn remove ( self ) -> V {
867+ pub fn remove ( self ) -> ( K , V ) {
743868 // Ensure that the search stack goes to a leaf. This is necessary to perform deletion
744869 // in a BTree. Note that this may put the tree in an inconsistent state (further
745870 // described in into_leaf's comments), but this is immediately fixed by the
@@ -1220,7 +1345,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
12201345 /// Takes the value of the entry out of the map, and returns it.
12211346 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
12221347 pub fn remove ( self ) -> V {
1223- self . stack . remove ( )
1348+ self . stack . remove ( ) . 1
12241349 }
12251350}
12261351
0 commit comments