diff --git a/src/inclusive_map.rs b/src/inclusive_map.rs index 76e6e09..15351be 100644 --- a/src/inclusive_map.rs +++ b/src/inclusive_map.rs @@ -2,6 +2,7 @@ use super::range_wrapper::RangeInclusiveStartWrapper; use crate::range_wrapper::RangeInclusiveEndWrapper; use crate::std_ext::*; use alloc::collections::BTreeMap; +use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::iter::FromIterator; @@ -527,11 +528,12 @@ where /// Gets an iterator over all the stored ranges that are /// either partially or completely overlapped by the given range. - pub fn overlapping<'a>(&'a self, range: &'a RangeInclusive) -> Overlapping { + pub fn overlapping>>(&self, range: R) -> Overlapping { // Find the first matching stored range by its _end_, // using sneaky layering and `Borrow` implementation. (See `range_wrappers` module.) - let start_sliver = - RangeInclusiveEndWrapper::new(range.start().clone()..=range.start().clone()); + let start_sliver = RangeInclusiveEndWrapper::new( + range.borrow().start().clone()..=range.borrow().start().clone(), + ); let btm_range_iter = self .btm .range::, RangeFrom<&RangeInclusiveEndWrapper>>( @@ -811,15 +813,18 @@ where /// documentation for more. /// /// [`overlapping`]: RangeInclusiveMap::overlapping -pub struct Overlapping<'a, K, V> { - query_range: &'a RangeInclusive, +pub struct Overlapping<'a, K, V, R: Borrow> = &'a RangeInclusive> { + query_range: R, btm_range_iter: alloc::collections::btree_map::Range<'a, RangeInclusiveStartWrapper, V>, } // `Overlapping` is always fused. (See definition of `next` below.) -impl<'a, K, V> core::iter::FusedIterator for Overlapping<'a, K, V> where K: Ord + Clone {} +impl<'a, K, V, R: Borrow>> core::iter::FusedIterator for Overlapping<'a, K, V, R> where + K: Ord + Clone +{ +} -impl<'a, K, V> Iterator for Overlapping<'a, K, V> +impl<'a, K, V, R: Borrow>> Iterator for Overlapping<'a, K, V, R> where K: Ord + Clone, { @@ -827,7 +832,7 @@ where fn next(&mut self) -> Option { if let Some((k, v)) = self.btm_range_iter.next() { - if k.start() <= self.query_range.end() { + if k.start() <= self.query_range.borrow().end() { Some((&k.range, v)) } else { // The rest of the items in the underlying iterator @@ -1503,7 +1508,7 @@ mod tests { // Overlapping tests #[test] - fn overlapping_with_empty_map() { + fn overlapping_ref_with_empty_map() { // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ let range_map: RangeInclusiveMap = RangeInclusiveMap::new(); @@ -1517,6 +1522,21 @@ mod tests { assert_eq!(overlapping.next(), None); } + #[test] + fn overlapping_owned_with_empty_map() { + // 0 1 2 3 4 5 6 7 8 9 + // ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ + let range_map: RangeInclusiveMap = RangeInclusiveMap::new(); + // 0 1 2 3 4 5 6 7 8 9 + // ◌ ◆-------------◆ ◌ + let query_range = 1..=8; + let mut overlapping = range_map.overlapping(query_range); + // Should not yield any items. + assert_eq!(overlapping.next(), None); + // Gaps iterator should be fused. + assert_eq!(overlapping.next(), None); + } + #[test] fn overlapping_partial_edges_complete_middle() { let mut range_map: RangeInclusiveMap = RangeInclusiveMap::new(); diff --git a/src/inclusive_set.rs b/src/inclusive_set.rs index fcc73c4..ff99a49 100644 --- a/src/inclusive_set.rs +++ b/src/inclusive_set.rs @@ -1,3 +1,4 @@ +use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::iter::FromIterator; @@ -189,7 +190,7 @@ where /// either partially or completely overlapped by the given range. /// /// The iterator element type is `RangeInclusive`. - pub fn overlapping<'a>(&'a self, range: &'a RangeInclusive) -> Overlapping { + pub fn overlapping>>(&self, range: R) -> Overlapping { Overlapping { inner: self.rm.overlapping(range), } @@ -393,14 +394,17 @@ where /// documentation for more. /// /// [`overlapping`]: RangeInclusiveSet::overlapping -pub struct Overlapping<'a, T> { - inner: crate::inclusive_map::Overlapping<'a, T, ()>, +pub struct Overlapping<'a, T, R: Borrow> = &'a RangeInclusive> { + inner: crate::inclusive_map::Overlapping<'a, T, (), R>, } // `Overlapping` is always fused. (See definition of `next` below.) -impl<'a, T> core::iter::FusedIterator for Overlapping<'a, T> where T: Ord + Clone {} +impl<'a, T, R: Borrow>> core::iter::FusedIterator for Overlapping<'a, T, R> where + T: Ord + Clone +{ +} -impl<'a, T> Iterator for Overlapping<'a, T> +impl<'a, T, R: Borrow>> Iterator for Overlapping<'a, T, R> where T: Ord + Clone, { diff --git a/src/map.rs b/src/map.rs index 84ae641..761b247 100644 --- a/src/map.rs +++ b/src/map.rs @@ -2,6 +2,7 @@ use super::range_wrapper::RangeStartWrapper; use crate::range_wrapper::RangeEndWrapper; use crate::std_ext::*; use alloc::collections::BTreeMap; +use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::iter::FromIterator; @@ -177,10 +178,11 @@ where /// Gets an iterator over all the stored ranges that are /// either partially or completely overlapped by the given range. - pub fn overlapping<'a>(&'a self, range: &'a Range) -> Overlapping { + pub fn overlapping>>(&self, range: R) -> Overlapping { // Find the first matching stored range by its _end_, // using sneaky layering and `Borrow` implementation. (See `range_wrappers` module.) - let start_sliver = RangeEndWrapper::new(range.start.clone()..range.start.clone()); + let start_sliver = + RangeEndWrapper::new(range.borrow().start.clone()..range.borrow().start.clone()); let btm_range_iter = self .btm .range::, (Bound<&RangeEndWrapper>, Bound<_>)>(( @@ -706,15 +708,18 @@ where /// documentation for more. /// /// [`overlapping`]: RangeMap::overlapping -pub struct Overlapping<'a, K, V> { - query_range: &'a Range, +pub struct Overlapping<'a, K, V, R: Borrow> = &'a Range> { + query_range: R, btm_range_iter: alloc::collections::btree_map::Range<'a, RangeStartWrapper, V>, } // `Overlapping` is always fused. (See definition of `next` below.) -impl<'a, K, V> core::iter::FusedIterator for Overlapping<'a, K, V> where K: Ord {} +impl<'a, K, V, R: Borrow>> core::iter::FusedIterator for Overlapping<'a, K, V, R> where + K: Ord +{ +} -impl<'a, K, V> Iterator for Overlapping<'a, K, V> +impl<'a, K, V, R: Borrow>> Iterator for Overlapping<'a, K, V, R> where K: Ord, { @@ -722,7 +727,7 @@ where fn next(&mut self) -> Option { if let Some((k, v)) = self.btm_range_iter.next() { - if k.start < self.query_range.end { + if k.start < self.query_range.borrow().end { Some((&k.range, v)) } else { // The rest of the items in the underlying iterator diff --git a/src/set.rs b/src/set.rs index 5947b21..e375244 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,3 +1,4 @@ +use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::iter::FromIterator; @@ -163,7 +164,7 @@ where /// either partially or completely overlapped by the given range. /// /// The iterator element type is `&Range`. - pub fn overlapping<'a>(&'a self, range: &'a Range) -> Overlapping { + pub fn overlapping>>(&self, range: R) -> Overlapping { Overlapping { inner: self.rm.overlapping(range), } @@ -361,14 +362,17 @@ where /// documentation for more. /// /// [`overlapping`]: RangeSet::overlapping -pub struct Overlapping<'a, T> { - inner: crate::map::Overlapping<'a, T, ()>, +pub struct Overlapping<'a, T, R: Borrow> = &'a Range> { + inner: crate::map::Overlapping<'a, T, (), R>, } // `Overlapping` is always fused. (See definition of `next` below.) -impl<'a, T> core::iter::FusedIterator for Overlapping<'a, T> where T: Ord + Clone {} +impl<'a, T, R: Borrow>> core::iter::FusedIterator for Overlapping<'a, T, R> where + T: Ord + Clone +{ +} -impl<'a, T> Iterator for Overlapping<'a, T> +impl<'a, T, R: Borrow>> Iterator for Overlapping<'a, T, R> where T: Ord + Clone, {