|
1 | 1 | use core::borrow::Borrow;
|
2 | 2 | use core::cmp::Ordering;
|
3 |
| -use core::ops::Bound::{Excluded, Included, Unbounded}; |
4 |
| -use core::ops::RangeBounds; |
| 3 | +use core::ops::{Bound, RangeBounds}; |
5 | 4 | use core::ptr;
|
6 | 5 |
|
7 | 6 | use super::node::{marker, ForceResult::*, Handle, NodeRef};
|
@@ -31,61 +30,76 @@ where
|
31 | 30 | let start = range.start_bound();
|
32 | 31 | let end = range.end_bound();
|
33 | 32 | match (start, end) {
|
34 |
| - (Excluded(s), Excluded(e)) if s == e => { |
| 33 | + (Bound::Excluded(s), Bound::Excluded(e)) if s == e => { |
35 | 34 | panic!("range start and end are equal and excluded in BTreeMap")
|
36 | 35 | }
|
37 |
| - (Included(s) | Excluded(s), Included(e) | Excluded(e)) if s > e => { |
| 36 | + (Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e)) |
| 37 | + if s > e => |
| 38 | + { |
38 | 39 | panic!("range start is greater than range end in BTreeMap")
|
39 | 40 | }
|
40 | 41 | _ => {}
|
41 | 42 | };
|
42 | 43 |
|
| 44 | + enum FullBound<T> { |
| 45 | + FullyIncluded, |
| 46 | + Included(T), |
| 47 | + Excluded(T), |
| 48 | + FullyExcluded, |
| 49 | + } |
| 50 | + use FullBound::*; |
| 51 | + impl<T> FullBound<T> { |
| 52 | + fn from(ops_bound: Bound<T>) -> Self { |
| 53 | + match ops_bound { |
| 54 | + Bound::Included(t) => Included(t), |
| 55 | + Bound::Excluded(t) => Excluded(t), |
| 56 | + Bound::Unbounded => FullyIncluded, |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + |
43 | 61 | let mut min_node = root1;
|
44 | 62 | let mut max_node = root2;
|
45 |
| - let mut min_found = false; |
46 |
| - let mut max_found = false; |
| 63 | + let mut min_bound = FullBound::from(start); |
| 64 | + let mut max_bound = FullBound::from(end); |
47 | 65 |
|
48 | 66 | loop {
|
49 |
| - // Using `range` again would be unsound (#81138) |
50 |
| - let front = match (min_found, start) { |
51 |
| - (false, Included(key)) => match min_node.search_node(key) { |
| 67 | + let front = match min_bound { |
| 68 | + Included(key) => match min_node.search_node(key) { |
52 | 69 | SearchResult::Found(kv) => {
|
53 |
| - min_found = true; |
| 70 | + min_bound = FullyExcluded; |
54 | 71 | kv.left_edge()
|
55 | 72 | }
|
56 | 73 | SearchResult::GoDown(edge) => edge,
|
57 | 74 | },
|
58 |
| - (false, Excluded(key)) => match min_node.search_node(key) { |
| 75 | + Excluded(key) => match min_node.search_node(key) { |
59 | 76 | SearchResult::Found(kv) => {
|
60 |
| - min_found = true; |
| 77 | + min_bound = FullyIncluded; |
61 | 78 | kv.right_edge()
|
62 | 79 | }
|
63 | 80 | SearchResult::GoDown(edge) => edge,
|
64 | 81 | },
|
65 |
| - (true, Included(_)) => min_node.last_edge(), |
66 |
| - (true, Excluded(_)) => min_node.first_edge(), |
67 |
| - (_, Unbounded) => min_node.first_edge(), |
| 82 | + FullyExcluded => min_node.last_edge(), |
| 83 | + FullyIncluded => min_node.first_edge(), |
68 | 84 | };
|
69 | 85 |
|
70 |
| - // Using `range` again would be unsound (#81138) |
71 |
| - let back = match (max_found, end) { |
72 |
| - (false, Included(key)) => match max_node.search_node(key) { |
| 86 | + let back = match max_bound { |
| 87 | + Included(key) => match max_node.search_node(key) { |
73 | 88 | SearchResult::Found(kv) => {
|
74 |
| - max_found = true; |
| 89 | + max_bound = FullyExcluded; |
75 | 90 | kv.right_edge()
|
76 | 91 | }
|
77 | 92 | SearchResult::GoDown(edge) => edge,
|
78 | 93 | },
|
79 |
| - (false, Excluded(key)) => match max_node.search_node(key) { |
| 94 | + Excluded(key) => match max_node.search_node(key) { |
80 | 95 | SearchResult::Found(kv) => {
|
81 |
| - max_found = true; |
| 96 | + max_bound = FullyIncluded; |
82 | 97 | kv.left_edge()
|
83 | 98 | }
|
84 | 99 | SearchResult::GoDown(edge) => edge,
|
85 | 100 | },
|
86 |
| - (true, Included(_)) => max_node.first_edge(), |
87 |
| - (true, Excluded(_)) => max_node.last_edge(), |
88 |
| - (_, Unbounded) => max_node.last_edge(), |
| 101 | + FullyExcluded => max_node.first_edge(), |
| 102 | + FullyIncluded => max_node.last_edge(), |
89 | 103 | };
|
90 | 104 |
|
91 | 105 | if front.partial_cmp(&back) == Some(Ordering::Greater) {
|
|
0 commit comments