diff --git a/README.md b/README.md index 8dda6fe..32a8c08 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,10 @@ assert_eq!(map.contains_point(5), true); ```rust use discrete_range_map::test_ranges::ie; -use discrete_range_map::DiscreteRangeMap; -use discrete_range_map::FiniteRange; +use discrete_range_map::{ + DiscreteFinite, DiscreteFiniteBounds, DiscreteRangeMap, + FiniteRange, +}; #[derive(Debug, Copy, Clone)] enum Reservation { @@ -52,20 +54,34 @@ enum Reservation { // First, we need to implement FiniteRange impl FiniteRange for Reservation { - fn start(&self) -> i8 { - match self { - Reservation::Finite(start, _) => *start, - Reservation::Infinite(start) => *start, - } - } - fn end(&self) -> i8 { - match self { - //the end is exclusive so we take off 1 with checking - //for compile time error overflow detection - Reservation::Finite(_, end) => end.checked_sub(1).unwrap(), - Reservation::Infinite(_) => i8::MAX, - } - } + fn start(&self) -> i8 { + match self { + Reservation::Finite(start, _) => *start, + Reservation::Infinite(start) => *start, + } + } + fn end(&self) -> i8 { + match self { + //the end is exclusive so we take off 1 with checking + //for compile time error overflow detection + Reservation::Finite(_, end) => end.down().unwrap(), + Reservation::Infinite(_) => i8::MAX, + } + } +} + +// Second, we need to implement From> +impl From> for Reservation { + fn from(bounds: DiscreteFiniteBounds) -> Self { + if bounds.end == i8::MAX { + Reservation::Infinite(bounds.start) + } else { + Reservation::Finite( + bounds.start, + bounds.end.up().unwrap(), + ) + } + } } // Next we can create a custom typed DiscreteRangeMap diff --git a/src/discrete_range_map.rs b/src/discrete_range_map.rs index 5509e98..c7c70b9 100644 --- a/src/discrete_range_map.rs +++ b/src/discrete_range_map.rs @@ -74,49 +74,6 @@ use crate::utils::{cmp_point_with_range, cut_range, is_valid_range, overlaps}; /// println!("{range:?}, {value:?}"); /// } /// ``` -/// Example using a custom range type: -/// ``` -/// use discrete_range_map::{DiscreteRangeMap, FiniteRange}; -/// -/// // An Exclusive-Exclusive range is not provided by any -/// // std::ops ranges so let't make our own!. -/// -/// #[derive(Debug, Copy, Clone, PartialEq)] -/// struct ExEx { -/// start: u8, -/// end: u8, -/// } -/// impl ExEx { -/// fn new(start: u8, end: u8) -> ExEx { -/// ExEx { start, end } -/// } -/// } -/// -/// // Implement FiniteRange on our new type -/// impl FiniteRange for ExEx { -/// fn start(&self) -> u8 { -/// //we are exclusive so need to step the values up -/// self.start.checked_add(1).unwrap() -/// } -/// fn end(&self) -> u8 { -/// //we are exclusive so need to step the values down -/// self.end.checked_sub(1).unwrap() -/// } -/// } -/// -/// // Now we can make a [`DiscreteRangeMap`] of [`ExEx`]s to `i8` -/// let mut map = DiscreteRangeMap::new(); -/// -/// map.insert_strict(ExEx::new(0, 5), 8).unwrap(); -/// map.insert_strict(ExEx::new(5, 7), 32).unwrap(); -/// -/// assert_eq!(map.contains_point(5), false); -/// -/// assert_eq!(map.get_at_point(9), None); -/// assert_eq!(map.get_at_point(6), Some(&32)); -/// -/// assert_eq!(map.get_entry_at_point(2), Ok((&ExEx::new(0, 5), &8))); -/// ``` /// /// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html #[derive(Debug, Clone, PartialEq, Eq)] @@ -528,9 +485,25 @@ where //optimisation, switch to BTreeMap::drain_range if it ever gets //implemented - return self - .inner - .drain_filter(move |inner_range, _| overlaps(*inner_range, range)); + //return self + //.inner + //.drain_filter(move |inner_range, _| overlaps(*inner_range, range)); + + let mut result = Vec::new(); + + let mut leftmost_cursor = self.inner.lower_bound_mut( + overlapping_comp(range.start()), + SearchBoundCustom::Included, + ); + + while leftmost_cursor + .key() + .is_some_and(|inner_range| overlaps(*inner_range, range)) + { + result.push(leftmost_cursor.remove_current().unwrap()); + } + + return result.into_iter(); } /// Cuts a given range out of the map and returns an iterator of diff --git a/src/lib.rs b/src/lib.rs index 555ee93..c046281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,8 +47,10 @@ along with discrete_range_map. If not, see . //! //! ```rust //! use discrete_range_map::test_ranges::ie; -//! use discrete_range_map::DiscreteRangeMap; -//! use discrete_range_map::FiniteRange; +//! use discrete_range_map::{ +//! DiscreteFinite, DiscreteFiniteBounds, DiscreteRangeMap, +//! FiniteRange, +//! }; //! //! #[derive(Debug, Copy, Clone)] //! enum Reservation { @@ -60,20 +62,34 @@ along with discrete_range_map. If not, see . //! //! // First, we need to implement FiniteRange //! impl FiniteRange for Reservation { -//! fn start(&self) -> i8 { -//! match self { -//! Reservation::Finite(start, _) => *start, -//! Reservation::Infinite(start) => *start, -//! } -//! } -//! fn end(&self) -> i8 { -//! match self { -//! //the end is exclusive so we take off 1 with checking -//! //for compile time error overflow detection -//! Reservation::Finite(_, end) => end.checked_sub(1).unwrap(), -//! Reservation::Infinite(_) => i8::MAX, -//! } -//! } +//! fn start(&self) -> i8 { +//! match self { +//! Reservation::Finite(start, _) => *start, +//! Reservation::Infinite(start) => *start, +//! } +//! } +//! fn end(&self) -> i8 { +//! match self { +//! //the end is exclusive so we take off 1 with checking +//! //for compile time error overflow detection +//! Reservation::Finite(_, end) => end.down().unwrap(), +//! Reservation::Infinite(_) => i8::MAX, +//! } +//! } +//! } +//! +//! // Second, we need to implement From> +//! impl From> for Reservation { +//! fn from(bounds: DiscreteFiniteBounds) -> Self { +//! if bounds.end == i8::MAX { +//! Reservation::Infinite(bounds.start) +//! } else { +//! Reservation::Finite( +//! bounds.start, +//! bounds.end.up().unwrap(), +//! ) +//! } +//! } //! } //! //! // Next we can create a custom typed DiscreteRangeMap @@ -262,5 +278,7 @@ pub mod discrete_range_set; pub use crate::discrete_finite::DiscreteFinite; pub use crate::discrete_finite_bounds::DiscreteFiniteBounds; -pub use crate::discrete_range_map::{DiscreteRangeMap, FiniteRange, OverlapError}; +pub use crate::discrete_range_map::{ + DiscreteRangeMap, FiniteRange, OverlapError, +}; pub use crate::discrete_range_set::DiscreteRangeSet; diff --git a/src/test_ranges.rs b/src/test_ranges.rs index ab67e21..a8fc1cd 100644 --- a/src/test_ranges.rs +++ b/src/test_ranges.rs @@ -1,5 +1,5 @@ -use crate::discrete_finite_bounds::DiscreteFiniteBounds; use crate::discrete_finite::DiscreteFinite; +use crate::discrete_finite_bounds::DiscreteFiniteBounds; pub fn uu() -> DiscreteFiniteBounds { DiscreteFiniteBounds {