@@ -714,6 +714,11 @@ impl<K: Ord, V> BTreeMap<K, V> {
714
714
/// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
715
715
/// range from 4 to 10.
716
716
///
717
+ /// # Panics
718
+ ///
719
+ /// Panics if range `start > end`.
720
+ /// Panics if range `start == end` and both bounds are `Excluded`.
721
+ ///
717
722
/// # Examples
718
723
///
719
724
/// Basic usage:
@@ -739,64 +744,11 @@ impl<K: Ord, V> BTreeMap<K, V> {
739
744
pub fn range < T : ?Sized , R > ( & self , range : R ) -> Range < K , V >
740
745
where T : Ord , K : Borrow < T > , R : RangeArgument < T >
741
746
{
742
- let min = range. start ( ) ;
743
- let max = range. end ( ) ;
744
- let front = match min {
745
- Included ( key) => {
746
- match search:: search_tree ( self . root . as_ref ( ) , key) {
747
- Found ( kv_handle) => {
748
- match kv_handle. left_edge ( ) . force ( ) {
749
- Leaf ( bottom) => bottom,
750
- Internal ( internal) => last_leaf_edge ( internal. descend ( ) ) ,
751
- }
752
- }
753
- GoDown ( bottom) => bottom,
754
- }
755
- }
756
- Excluded ( key) => {
757
- match search:: search_tree ( self . root . as_ref ( ) , key) {
758
- Found ( kv_handle) => {
759
- match kv_handle. right_edge ( ) . force ( ) {
760
- Leaf ( bottom) => bottom,
761
- Internal ( internal) => first_leaf_edge ( internal. descend ( ) ) ,
762
- }
763
- }
764
- GoDown ( bottom) => bottom,
765
- }
766
- }
767
- Unbounded => first_leaf_edge ( self . root . as_ref ( ) ) ,
768
- } ;
747
+ let root1 = self . root . as_ref ( ) ;
748
+ let root2 = self . root . as_ref ( ) ;
749
+ let ( f, b) = range_search ( root1, root2, range) ;
769
750
770
- let back = match max {
771
- Included ( key) => {
772
- match search:: search_tree ( self . root . as_ref ( ) , key) {
773
- Found ( kv_handle) => {
774
- match kv_handle. right_edge ( ) . force ( ) {
775
- Leaf ( bottom) => bottom,
776
- Internal ( internal) => first_leaf_edge ( internal. descend ( ) ) ,
777
- }
778
- }
779
- GoDown ( bottom) => bottom,
780
- }
781
- }
782
- Excluded ( key) => {
783
- match search:: search_tree ( self . root . as_ref ( ) , key) {
784
- Found ( kv_handle) => {
785
- match kv_handle. left_edge ( ) . force ( ) {
786
- Leaf ( bottom) => bottom,
787
- Internal ( internal) => last_leaf_edge ( internal. descend ( ) ) ,
788
- }
789
- }
790
- GoDown ( bottom) => bottom,
791
- }
792
- }
793
- Unbounded => last_leaf_edge ( self . root . as_ref ( ) ) ,
794
- } ;
795
-
796
- Range {
797
- front : front,
798
- back : back,
799
- }
751
+ Range { front : f, back : b}
800
752
}
801
753
802
754
/// Constructs a mutable double-ended iterator over a sub-range of elements in the map.
@@ -806,6 +758,11 @@ impl<K: Ord, V> BTreeMap<K, V> {
806
758
/// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
807
759
/// range from 4 to 10.
808
760
///
761
+ /// # Panics
762
+ ///
763
+ /// Panics if range `start > end`.
764
+ /// Panics if range `start == end` and both bounds are `Excluded`.
765
+ ///
809
766
/// # Examples
810
767
///
811
768
/// Basic usage:
@@ -831,66 +788,13 @@ impl<K: Ord, V> BTreeMap<K, V> {
831
788
pub fn range_mut < T : ?Sized , R > ( & mut self , range : R ) -> RangeMut < K , V >
832
789
where T : Ord , K : Borrow < T > , R : RangeArgument < T >
833
790
{
834
- let min = range. start ( ) ;
835
- let max = range. end ( ) ;
836
791
let root1 = self . root . as_mut ( ) ;
837
792
let root2 = unsafe { ptr:: read ( & root1) } ;
838
-
839
- let front = match min {
840
- Included ( key) => {
841
- match search:: search_tree ( root1, key) {
842
- Found ( kv_handle) => {
843
- match kv_handle. left_edge ( ) . force ( ) {
844
- Leaf ( bottom) => bottom,
845
- Internal ( internal) => last_leaf_edge ( internal. descend ( ) ) ,
846
- }
847
- }
848
- GoDown ( bottom) => bottom,
849
- }
850
- }
851
- Excluded ( key) => {
852
- match search:: search_tree ( root1, key) {
853
- Found ( kv_handle) => {
854
- match kv_handle. right_edge ( ) . force ( ) {
855
- Leaf ( bottom) => bottom,
856
- Internal ( internal) => first_leaf_edge ( internal. descend ( ) ) ,
857
- }
858
- }
859
- GoDown ( bottom) => bottom,
860
- }
861
- }
862
- Unbounded => first_leaf_edge ( root1) ,
863
- } ;
864
-
865
- let back = match max {
866
- Included ( key) => {
867
- match search:: search_tree ( root2, key) {
868
- Found ( kv_handle) => {
869
- match kv_handle. right_edge ( ) . force ( ) {
870
- Leaf ( bottom) => bottom,
871
- Internal ( internal) => first_leaf_edge ( internal. descend ( ) ) ,
872
- }
873
- }
874
- GoDown ( bottom) => bottom,
875
- }
876
- }
877
- Excluded ( key) => {
878
- match search:: search_tree ( root2, key) {
879
- Found ( kv_handle) => {
880
- match kv_handle. left_edge ( ) . force ( ) {
881
- Leaf ( bottom) => bottom,
882
- Internal ( internal) => last_leaf_edge ( internal. descend ( ) ) ,
883
- }
884
- }
885
- GoDown ( bottom) => bottom,
886
- }
887
- }
888
- Unbounded => last_leaf_edge ( root2) ,
889
- } ;
793
+ let ( f, b) = range_search ( root1, root2, range) ;
890
794
891
795
RangeMut {
892
- front : front ,
893
- back : back ,
796
+ front : f ,
797
+ back : b ,
894
798
_marker : PhantomData ,
895
799
}
896
800
}
@@ -1827,6 +1731,80 @@ fn last_leaf_edge<BorrowType, K, V>
1827
1731
}
1828
1732
}
1829
1733
1734
+ fn range_search < BorrowType , K , V , Q : ?Sized , R : RangeArgument < Q > > (
1735
+ root1 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
1736
+ root2 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
1737
+ range : R
1738
+ ) -> ( Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
1739
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > )
1740
+ where Q : Ord , K : Borrow < Q >
1741
+ {
1742
+ match ( range. start ( ) , range. end ( ) ) {
1743
+ ( Excluded ( s) , Excluded ( e) ) if s==e =>
1744
+ panic ! ( "range start and end are equal and excluded in BTreeMap" ) ,
1745
+ ( Included ( s) , Included ( e) ) |
1746
+ ( Included ( s) , Excluded ( e) ) |
1747
+ ( Excluded ( s) , Included ( e) ) |
1748
+ ( Excluded ( s) , Excluded ( e) ) if s>e =>
1749
+ panic ! ( "range start is greater than range end in BTreeMap" ) ,
1750
+ _ => { } ,
1751
+ } ;
1752
+
1753
+ let mut min_node = root1;
1754
+ let mut max_node = root2;
1755
+ let mut min_found = false ;
1756
+ let mut max_found = false ;
1757
+ let mut diverged = false ;
1758
+
1759
+ loop {
1760
+ let min_edge = match ( min_found, range. start ( ) ) {
1761
+ ( false , Included ( key) ) => match search:: search_linear ( & min_node, key) {
1762
+ ( i, true ) => { min_found = true ; i } ,
1763
+ ( i, false ) => i,
1764
+ } ,
1765
+ ( false , Excluded ( key) ) => match search:: search_linear ( & min_node, key) {
1766
+ ( i, true ) => { min_found = true ; i+1 } ,
1767
+ ( i, false ) => i,
1768
+ } ,
1769
+ ( _, Unbounded ) => 0 ,
1770
+ ( true , Included ( _) ) => min_node. keys ( ) . len ( ) ,
1771
+ ( true , Excluded ( _) ) => 0 ,
1772
+ } ;
1773
+
1774
+ let max_edge = match ( max_found, range. end ( ) ) {
1775
+ ( false , Included ( key) ) => match search:: search_linear ( & max_node, key) {
1776
+ ( i, true ) => { max_found = true ; i+1 } ,
1777
+ ( i, false ) => i,
1778
+ } ,
1779
+ ( false , Excluded ( key) ) => match search:: search_linear ( & max_node, key) {
1780
+ ( i, true ) => { max_found = true ; i } ,
1781
+ ( i, false ) => i,
1782
+ } ,
1783
+ ( _, Unbounded ) => max_node. keys ( ) . len ( ) ,
1784
+ ( true , Included ( _) ) => 0 ,
1785
+ ( true , Excluded ( _) ) => max_node. keys ( ) . len ( ) ,
1786
+ } ;
1787
+
1788
+ if !diverged {
1789
+ if max_edge < min_edge { panic ! ( "Ord is ill-defined in BTreeMap range" ) }
1790
+ if min_edge != max_edge { diverged = true ; }
1791
+ }
1792
+
1793
+ let front = Handle :: new_edge ( min_node, min_edge) ;
1794
+ let back = Handle :: new_edge ( max_node, max_edge) ;
1795
+ match ( front. force ( ) , back. force ( ) ) {
1796
+ ( Leaf ( f) , Leaf ( b) ) => {
1797
+ return ( f, b) ;
1798
+ } ,
1799
+ ( Internal ( min_int) , Internal ( max_int) ) => {
1800
+ min_node = min_int. descend ( ) ;
1801
+ max_node = max_int. descend ( ) ;
1802
+ } ,
1803
+ _ => unreachable ! ( "BTreeMap has different depths" ) ,
1804
+ } ;
1805
+ }
1806
+ }
1807
+
1830
1808
#[ inline( always) ]
1831
1809
unsafe fn unwrap_unchecked < T > ( val : Option < T > ) -> T {
1832
1810
val. unwrap_or_else ( || {
0 commit comments