impl DoubleEndedIterator for ManagedMapRange.

This commit is contained in:
Valentin Lorentz 2018-05-26 06:11:48 +02:00 committed by whitequark
parent 3d55592b98
commit 69c1a40aa9
1 changed files with 73 additions and 11 deletions

View File

@ -91,32 +91,56 @@ impl<T> Into<Option<T>> for RevOption<T> {
} }
} }
pub enum Range<'a, K: 'a, V: 'a> { #[derive(Debug, Clone)]
enum RangeInner<'a, K: 'a, V: 'a> {
/// Borrowed variant. /// Borrowed variant.
Borrowed(&'a [Option<(K, V)>], usize), Borrowed { slice: &'a [Option<(K, V)>], begin: usize, end: usize },
/// Owned variant, only available with the `std` or `alloc` feature enabled. /// Owned variant, only available with the `std` or `alloc` feature enabled.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
Owned(BTreeRange<'a, K, V>), Owned(BTreeRange<'a, K, V>),
} }
#[derive(Debug, Clone)]
pub struct Range<'a, K: 'a, V: 'a>(RangeInner<'a, K, V>);
impl<'a, K: 'a, V: 'a> Iterator for Range<'a, K, V> { impl<'a, K: 'a, V: 'a> Iterator for Range<'a, K, V> {
type Item = (&'a K, &'a V); type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match *self { match self.0 {
Range::Borrowed(ref slice, ref mut index) => { RangeInner::Borrowed { ref slice, ref mut begin, ref end } => {
*index += 1; *begin += 1;
if *index-1 >= slice.len() { if *begin-1 >= *end {
None None
} else { } else {
match slice[*index-1] { match slice[*begin-1] {
None => None, None => None,
Some((ref k, ref v)) => Some((k, v)) Some((ref k, ref v)) => Some((k, v))
} }
} }
}, },
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
Range::Owned(ref mut range) => range.next(), RangeInner::Owned(ref mut range) => range.next(),
}
}
}
impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Range<'a, K, V> {
fn next_back(&mut self) -> Option<Self::Item> {
match self.0 {
RangeInner::Borrowed { ref slice, ref begin, ref mut end } => {
if *begin >= *end {
None
} else {
*end -= 1;
match slice[*end] {
None => None,
Some((ref k, ref v)) => Some((k, v))
}
}
},
#[cfg(any(feature = "std", feature = "alloc"))]
RangeInner::Owned(ref mut range) => range.next_back(),
} }
} }
} }
@ -275,13 +299,15 @@ impl<'a, K: Ord + 'a, V: 'a> ManagedMap<'a, K, V> {
match self { match self {
&ManagedMap::Borrowed(ref pairs) => { &ManagedMap::Borrowed(ref pairs) => {
match binary_search_by_key_range(&pairs[0..self.len()], range) { match binary_search_by_key_range(&pairs[0..self.len()], range) {
Ok((begin, end)) => Range::Borrowed(&pairs[begin..end], 0), Ok((begin, end)) => Range(RangeInner::Borrowed {
Err(()) => Range::Borrowed(&[], 0), slice: &pairs[begin..end], begin: 0, end: end-begin }),
Err(()) => Range(RangeInner::Borrowed {
slice: &[], begin: 0, end: 0 }),
} }
}, },
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
&ManagedMap::Owned(ref map) => { &ManagedMap::Owned(ref map) => {
Range::Owned(map.range(range)) Range(RangeInner::Owned(map.range(range)))
}, },
} }
} }
@ -551,16 +577,27 @@ mod test {
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range("a"..);
assert_eq!(range.next(), Some((&"a", &1)));
assert_eq!(range.next_back(), Some((&"d", &4)));
assert_eq!(range.next_back(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"b", &2)));
assert_eq!(range.next_back(), None);
assert_eq!(range.next(), None);
let mut range = map.range("b"..); let mut range = map.range("b"..);
assert_eq!(range.next(), Some((&"b", &2))); assert_eq!(range.next(), Some((&"b", &2)));
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range("d"..); let mut range = map.range("d"..);
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range(.."e"); let mut range = map.range(.."e");
assert_eq!(range.next(), Some((&"a", &1))); assert_eq!(range.next(), Some((&"a", &1)));
@ -568,19 +605,23 @@ mod test {
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range(.."d"); let mut range = map.range(.."d");
assert_eq!(range.next(), Some((&"a", &1))); assert_eq!(range.next(), Some((&"a", &1)));
assert_eq!(range.next(), Some((&"b", &2))); assert_eq!(range.next(), Some((&"b", &2)));
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range(.."b"); let mut range = map.range(.."b");
assert_eq!(range.next(), Some((&"a", &1))); assert_eq!(range.next(), Some((&"a", &1)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range(.."a"); let mut range = map.range(.."a");
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
let mut range = map.range::<&str, _>(..); let mut range = map.range::<&str, _>(..);
assert_eq!(range.next(), Some((&"a", &1))); assert_eq!(range.next(), Some((&"a", &1)));
@ -588,6 +629,7 @@ mod test {
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
assert_eq!(range.next_back(), None);
} }
#[test] #[test]
@ -639,6 +681,26 @@ mod test {
assert_eq!(range.next(), Some((&"c", &3))); assert_eq!(range.next(), Some((&"c", &3)));
assert_eq!(range.next(), Some((&"d", &4))); assert_eq!(range.next(), Some((&"d", &4)));
assert_eq!(range.next(), None); assert_eq!(range.next(), None);
let mut range = map.range::<&str, _>((Included("b"), Included("a")));
assert_eq!(range.next_back(), None);
let mut range = map.range::<&str, _>((Included("b"), Included("b")));
assert_eq!(range.next_back(), Some((&"b", &2)));
assert_eq!(range.next_back(), None);
let mut range = map.range::<&str, _>((Included("b"), Included("c")));
assert_eq!(range.next_back(), Some((&"c", &3)));
assert_eq!(range.next_back(), Some((&"b", &2)));
assert_eq!(range.next_back(), None);
let mut range = map.range::<&str, _>((Included("b"), Included("d")));
assert_eq!(range.next_back(), Some((&"d", &4)));
assert_eq!(range.next_back(), Some((&"c", &3)));
assert_eq!(range.next_back(), Some((&"b", &2)));
assert_eq!(range.next_back(), None);
let mut range = map.range::<&str, _>((Included("b"), Included("e")));
assert_eq!(range.next_back(), Some((&"d", &4)));
assert_eq!(range.next_back(), Some((&"c", &3)));
assert_eq!(range.next_back(), Some((&"b", &2)));
assert_eq!(range.next_back(), None);
} }
#[test] #[test]