diff --git a/src/helpers.rs b/src/helpers.rs index b7fcfe2..07c83df 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -23,19 +23,20 @@ use std::ops::{Bound, RangeBounds}; use labels::{tested, trivial}; use crate::bound_ord::BoundOrd; +use crate::range_bounds_map::NiceRange; use crate::{TryFromBounds, TryFromBoundsError}; -pub(crate) fn cmp_range_bounds_with_bound_ord( - range_bounds: &A, - bound_ord: BoundOrd<&B>, +pub(crate) fn cmp_range_with_bound_ord( + range: A, + bound_ord: BoundOrd, ) -> Ordering where - A: RangeBounds, + A: NiceRange, B: Ord, { - if bound_ord < BoundOrd::start(range_bounds.start_bound()) { + if bound_ord < BoundOrd::start(range.start()) { Ordering::Less - } else if bound_ord > BoundOrd::end(range_bounds.end_bound()) { + } else if bound_ord > BoundOrd::end(range.end()) { Ordering::Greater } else { Ordering::Equal @@ -54,20 +55,17 @@ enum Config { } #[tested] -fn config(a: &A, b: &B) -> Config +fn config(a: A, b: B) -> Config where - A: RangeBounds, - B: RangeBounds, + A: NiceRange, + B: NiceRange, I: Ord, { - let (a_start, a_end) = expand(a); - let (b_start, b_end) = expand(b); - - match BoundOrd::start(a_start) < BoundOrd::start(b_start) { + match BoundOrd::start(a.start()) < BoundOrd::start(b.start()) { true => { match ( - contains_bound_ord(a, BoundOrd::start(b_start)), - contains_bound_ord(a, BoundOrd::end(b_end)), + contains_bound_ord(a, BoundOrd::start(b.start())), + contains_bound_ord(a, BoundOrd::end(b.end())), ) { (false, false) => Config::LeftFirstNonOverlapping, (true, false) => Config::LeftFirstPartialOverlap, @@ -77,8 +75,8 @@ where } false => { match ( - contains_bound_ord(b, BoundOrd::start(a_start)), - contains_bound_ord(b, BoundOrd::end(a_end)), + contains_bound_ord(b, BoundOrd::start(a.start())), + contains_bound_ord(b, BoundOrd::end(a.end())), ) { (false, false) => Config::RightFirstNonOverlapping, (true, false) => Config::RightFirstPartialOverlap, @@ -96,16 +94,16 @@ enum SortedConfig { Swallowed((Bound, Bound), (Bound, Bound)), } -#[rustfmt::skip]//{{{//{{{//{{{//{{{ -#[trivial]//}}}//}}}//}}}//}}} -fn sorted_config<'a, I, A, B>(a: &'a A, b: &'a B) -> SortedConfig<&'a I> +#[rustfmt::skip] +#[trivial] +fn sorted_config(a: A, b: B) -> SortedConfig where - A: RangeBounds, - B: RangeBounds, + A: NiceRange, + B: NiceRange, I: Ord, { - let ae = expand(a); - let be = expand(b); + let ae = (a.start(), a.end()); + let be = (b.start(), b.end()); match config(a, b) { Config::LeftFirstNonOverlapping => SortedConfig::NonOverlapping(ae, be), Config::LeftFirstPartialOverlap => SortedConfig::Swallowed(ae, be), @@ -119,15 +117,15 @@ where #[trivial] pub(crate) fn contains_bound_ord( - range_bounds: &A, - bound_ord: BoundOrd<&I>, + range_bounds: A, + bound_ord: BoundOrd, ) -> bool where - A: RangeBounds, + A: NiceRange, I: Ord, { - let start_bound_ord = BoundOrd::start(range_bounds.start_bound()); - let end_bound_ord = BoundOrd::end(range_bounds.end_bound()); + let start_bound_ord = BoundOrd::start(range_bounds.start()); + let end_bound_ord = BoundOrd::end(range_bounds.end()); return bound_ord >= start_bound_ord && bound_ord <= end_bound_ord; } @@ -140,57 +138,48 @@ struct CutResult { } #[tested] -pub(crate) fn cut_range_bounds<'a, I, B, C>( - base_range_bounds: &'a B, - cut_range_bounds: &'a C, -) -> CutResult<&'a I> +pub(crate) fn cut_range_bounds(base: B, cut: C) -> CutResult where - B: RangeBounds, - C: RangeBounds, + B: NiceRange, + C: NiceRange, I: Ord + Clone, { - let base_all @ (base_start, base_end) = ( - base_range_bounds.start_bound(), - base_range_bounds.end_bound(), - ); - let cut_all @ (cut_start, cut_end) = - (cut_range_bounds.start_bound(), cut_range_bounds.end_bound()); - let mut result = CutResult { before_cut: None, inside_cut: None, after_cut: None, }; - match config(base_range_bounds, cut_range_bounds) { + match config(base, cut) { Config::LeftFirstNonOverlapping => { - result.before_cut = Some(base_all); + result.before_cut = Some((base.start(), base.end())); } Config::LeftFirstPartialOverlap => { - result.before_cut = Some((base_start, flip_bound(cut_start))); - result.inside_cut = Some((cut_start, base_end)); + result.before_cut = Some((base.start(), flip_bound(cut.start()))); + result.inside_cut = Some((cut.start(), base.end())); } Config::LeftContainsRight => { - result.before_cut = Some((base_start, flip_bound(cut_start))); - result.inside_cut = Some(cut_all); + result.before_cut = Some((base.start(), flip_bound(cut.start()))); + result.inside_cut = Some((cut.start(), cut.end())); // exception for Unbounded-ending things - match cut_end { + match cut.end() { Bound::Unbounded => {} _ => { - result.after_cut = Some((flip_bound(cut_end), base_end)); + result.after_cut = + Some((flip_bound(cut.end()), base.end())); } } } Config::RightFirstNonOverlapping => { - result.after_cut = Some(base_all); + result.after_cut = Some((base.start(), base.end())); } Config::RightFirstPartialOverlap => { - result.after_cut = Some((flip_bound(cut_end), base_end)); - result.inside_cut = Some((base_start, cut_end)); + result.after_cut = Some((flip_bound(cut.end()), base.end())); + result.inside_cut = Some((base.start(), cut.end())); } Config::RightContainsLeft => { - result.inside_cut = Some(base_all); + result.inside_cut = Some((base.start(), base.end())); } } @@ -224,10 +213,10 @@ where } #[tested] -pub fn overlaps(a: &A, b: &B) -> bool +pub fn overlaps(a: A, b: B) -> bool where - A: RangeBounds, - B: RangeBounds, + A: NiceRange, + B: NiceRange, I: Ord, { !matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _)) @@ -254,14 +243,6 @@ where } } -#[trivial] -fn expand(range_bounds: &A) -> (Bound<&I>, Bound<&I>) -where - A: RangeBounds, -{ - (range_bounds.start_bound(), range_bounds.end_bound()) -} - #[trivial] pub(crate) fn flip_bound(bound: Bound) -> Bound { match bound { @@ -273,12 +254,12 @@ pub(crate) fn flip_bound(bound: Bound) -> Bound { //assumes the bound overlaps the range_bounds pub(crate) fn split_off_right_section( - range_bounds: &&K, + range_bounds: K, with_bound: Bound, ) -> (Option>, (Bound, Bound)) where - I: Clone + Ord, - K: RangeBounds + TryFromBounds, + I: Ord, + K: NiceRange + TryFromBounds, { let (start_bound, end_bound) = (range_bounds.start_bound(), range_bounds.end_bound()); diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index bbe684e..68fc4e8 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -276,8 +276,8 @@ pub enum OverlapOrTryFromBoundsError { impl RangeBoundsMap where - I: Ord, - K: RangeBounds, + I: Ord + Copy, + K: NiceRange + Copy, { /// Makes a new, empty `RangeBoundsMap`. /// @@ -402,8 +402,8 @@ where where Q: RangeBounds, { - let lower_comp = comp_start(range_bounds.start_bound()); - let upper_comp = comp_end(range_bounds.end_bound()); + let lower_comp = comp_start(range_bounds.start()); + let upper_comp = comp_end(range_bounds.end()); let lower_bound = SearchBoundCustom::Included; let upper_bound = SearchBoundCustom::Included; @@ -432,7 +432,7 @@ where /// assert_eq!(map.get_at_point(&101), None); /// ``` #[trivial] - pub fn get_at_point(&self, point: &I) -> Option<&V> { + pub fn get_at_point(&self, point: I) -> Option<&V> { self.get_entry_at_point(point).map(|(key, value)| value) } @@ -499,7 +499,7 @@ where /// assert_eq!(map.get_entry_at_point(&101), None); /// ``` #[trivial] - pub fn get_entry_at_point(&self, point: &I) -> Option<(&K, &V)> { + pub fn get_entry_at_point(&self, point: I) -> Option<(&K, &V)> { self.inner.get_key_value(comp_start(Bound::Included(point))) } @@ -1034,12 +1034,12 @@ where ) -> Result<&K, OverlapOrTryFromBoundsError> { todo!() } - #[parent_tested] - fn touching_left(&self, range_bounds: &K) -> Option<&K> {} - #[parent_tested] - fn touching_right(&self, range_bounds: &K) -> Option<&K> { - todo!() - } + //#[parent_tested] + //fn touching_left(&self, range_bounds: K) -> Option {} + //#[parent_tested] + //fn touching_right(&self, range_bounds: K) -> Option { + //todo!() + //} /// Adds a new (`RangeBounds`, `Value`) entry to the map and /// merges into other `RangeBounds` in the map which overlap @@ -1296,26 +1296,26 @@ where } } -fn comp_start(bound: Bound<&I>) -> impl FnMut(&K) -> Ordering + '_ +fn comp_start(bound: Bound) -> impl FnMut(&K) -> Ordering where - I: Ord, - K: RangeBounds, + I: Ord + Copy + Clone, + K: NiceRange + Copy, { move |inner_range_bounds: &K| { cmp_range_bounds_with_bound_ord( - inner_range_bounds, + *inner_range_bounds, BoundOrd::start(bound), ) } } -fn comp_end(bound: Bound<&I>) -> impl FnMut(&K) -> Ordering + '_ +fn comp_end(bound: Bound) -> impl FnMut(&K) -> Ordering where - I: Ord, - K: RangeBounds, + I: Ord + Copy + Clone, + K: NiceRange + Copy, { move |inner_range_bounds: &K| { cmp_range_bounds_with_bound_ord( - inner_range_bounds, + *inner_range_bounds, BoundOrd::end(bound), ) } @@ -1330,3 +1330,21 @@ where .cmp(&BoundOrd::start(inner_range_bounds.start_bound())) } } + +pub trait NiceRange { + fn start(&self) -> Bound; + fn end(&self) -> Bound; +} + +impl NiceRange for K +where + I: Clone, + K: RangeBounds, +{ + fn start(&self) -> Bound { + self.start_bound().cloned() + } + fn end(&self) -> Bound { + self.end_bound().cloned() + } +}