diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index c6a3b2e..7579a89 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -1419,8 +1419,8 @@ where value: V, ) -> Result<(), TryFromBoundsError> where - V: Clone, K: TryFromBounds, + V: Clone, { let _ = self.cut(&range_bounds)?; self.insert_strict(range_bounds, value).unwrap(); @@ -1472,14 +1472,13 @@ where self.iter().next_back() } - /// Moves all elements from `other` into `self` by + /// Moves all elements from `other` into `self` using /// [`RangeBoundsMap::insert_strict()`] in ascending order, /// leaving `other` empty. /// - /// If any of the `RangeBounds` in `other` overlap `self` then - /// that `RangeBounds` is not inserted and the function returns. - /// This will mean all `RangeBounds` after the failed one will not - /// be inserted into `self`. + /// If the underlying [`RangeBoundsMap::insert_strict()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. /// /// # Examples /// ``` @@ -1522,6 +1521,221 @@ where return Ok(()); } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsMap::insert_merge_touching()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_touching()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut base = RangeBoundsMap::from_slice_merge_touching([ + /// (1..4, false), + /// (4..8, true), + /// ]) + /// .unwrap(); + /// + /// let mut add = RangeBoundsMap::from_slice_merge_touching([ + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// let expected = RangeBoundsMap::from_slice_merge_touching([ + /// (1..4, false), + /// (4..8, true), + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_merge_touching(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_touching( + &mut self, + other: &mut RangeBoundsMap, + ) -> Result<(), OverlapOrTryFromBoundsError> + where + K: TryFromBounds, + { + for (range_bounds, value) in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_touching(range_bounds, value)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsMap::insert_merge_overlapping()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_overlapping()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut base = RangeBoundsMap::from_slice_merge_overlapping([ + /// (1..4, false), + /// (4..8, true), + /// ]) + /// .unwrap(); + /// + /// let mut add = RangeBoundsMap::from_slice_merge_overlapping([ + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// let expected = RangeBoundsMap::from_slice_merge_overlapping([ + /// (1..4, false), + /// (4..8, true), + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_merge_overlapping(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_overlapping( + &mut self, + other: &mut RangeBoundsMap, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + { + for (range_bounds, value) in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_overlapping(range_bounds, value)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsMap::insert_merge_touching_or_overlapping()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_touching_or_overlapping()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut base = + /// RangeBoundsMap::from_slice_merge_touching_or_overlapping([ + /// (1..4, false), + /// (4..8, true), + /// ]) + /// .unwrap(); + /// + /// let mut add = + /// RangeBoundsMap::from_slice_merge_touching_or_overlapping([ + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// let expected = + /// RangeBoundsMap::from_slice_merge_touching_or_overlapping([ + /// (1..4, false), + /// (4..8, true), + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!( + /// base.append_merge_touching_or_overlapping(&mut add), + /// Ok(()) + /// ); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_touching_or_overlapping( + &mut self, + other: &mut RangeBoundsMap, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + { + for (range_bounds, value) in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_touching_or_overlapping(range_bounds, value)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsMap::insert_overwrite()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_overwrite()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut base = RangeBoundsMap::from_slice_overwrite([ + /// (1..4, false), + /// (4..8, true), + /// ]) + /// .unwrap(); + /// + /// let mut add = RangeBoundsMap::from_slice_overwrite([ + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// let expected = RangeBoundsMap::from_slice_overwrite([ + /// (1..4, false), + /// (4..8, true), + /// (10..38, true), + /// (40..42, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_overwrite(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_overwrite( + &mut self, + other: &mut RangeBoundsMap, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + V: Clone, + { + for (range_bounds, value) in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_overwrite(range_bounds, value)?; + } + + return Ok(()); + } /// Splits the map in two at the given `start_bound()`. Returns /// the full or partial `RangeBounds` after the split. @@ -1894,8 +2108,8 @@ where slice: [(K, V); N], ) -> Result, TryFromBoundsError> where - V: Clone, K: TryFromBounds, + V: Clone, { let mut map = RangeBoundsMap::new(); for (range_bounds, value) in slice { diff --git a/src/range_bounds_set.rs b/src/range_bounds_set.rs index 2a30022..a6ef124 100644 --- a/src/range_bounds_set.rs +++ b/src/range_bounds_set.rs @@ -812,14 +812,13 @@ where self.map.last_entry().map(|(key, _)| key) } - /// Moves all elements from `other` into `self` by - /// [`RangeBoundsSet::insert_strict()`] in acending order, + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsSet::insert_strict()`] in ascending order, /// leaving `other` empty. /// - /// If any of the `RangeBounds` in `other` overlap `self` then - /// that `RangeBounds` is not inserted and the function returns. - /// This will mean all `RangeBounds` after the failed one will not - /// be inserted into `self`. + /// If the underlying [`RangeBoundsMap::insert_strict()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. /// /// # Examples /// ``` @@ -856,6 +855,209 @@ where return Ok(()); } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsSet::insert_merge_touching()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_touching()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsSet; + /// + /// let mut base = + /// RangeBoundsSet::from_slice_merge_touching([1..4, 4..8]) + /// .unwrap(); + /// + /// let mut add = + /// RangeBoundsSet::from_slice_merge_touching([10..38, 40..42]) + /// .unwrap(); + /// + /// let expected = RangeBoundsSet::from_slice_merge_touching([ + /// 1..4, + /// 4..8, + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_merge_touching(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_touching( + &mut self, + other: &mut RangeBoundsSet, + ) -> Result<(), OverlapOrTryFromBoundsError> + where + K: TryFromBounds, + { + for range_bounds in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_touching(range_bounds)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsSet::insert_merge_overlapping()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_overlapping()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsSet; + /// + /// let mut base = + /// RangeBoundsSet::from_slice_merge_overlapping([1..4, 4..8]) + /// .unwrap(); + /// + /// let mut add = RangeBoundsSet::from_slice_merge_overlapping([ + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// let expected = RangeBoundsSet::from_slice_merge_overlapping([ + /// 1..4, + /// 4..8, + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_merge_overlapping(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_overlapping( + &mut self, + other: &mut RangeBoundsSet, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + { + for range_bounds in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_overlapping(range_bounds)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsSet::insert_merge_touching_or_overlapping()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_merge_touching_or_overlapping()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsSet; + /// + /// let mut base = + /// RangeBoundsSet::from_slice_merge_touching_or_overlapping([ + /// 1..4, + /// 4..8, + /// ]) + /// .unwrap(); + /// + /// let mut add = + /// RangeBoundsSet::from_slice_merge_touching_or_overlapping([ + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// let expected = + /// RangeBoundsSet::from_slice_merge_touching_or_overlapping([ + /// 1..4, + /// 4..8, + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// assert_eq!( + /// base.append_merge_touching_or_overlapping(&mut add), + /// Ok(()) + /// ); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_merge_touching_or_overlapping( + &mut self, + other: &mut RangeBoundsSet, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + { + for range_bounds in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_merge_touching_or_overlapping(range_bounds)?; + } + + return Ok(()); + } + /// Moves all elements from `other` into `self` using + /// [`RangeBoundsSet::insert_overwrite()`] in ascending order, + /// leaving `other` empty. + /// + /// If the underlying [`RangeBoundsMap::insert_overwrite()`] returns + /// an `Err` at any point, then the element it failed on and all + /// those following are dropped, but not inserted into `self`. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsSet; + /// + /// let mut base = + /// RangeBoundsSet::from_slice_overwrite([1..4, 4..8]).unwrap(); + /// + /// let mut add = + /// RangeBoundsSet::from_slice_overwrite([10..38, 40..42]) + /// .unwrap(); + /// + /// let expected = RangeBoundsSet::from_slice_overwrite([ + /// 1..4, + /// 4..8, + /// 10..38, + /// 40..42, + /// ]) + /// .unwrap(); + /// + /// assert_eq!(base.append_overwrite(&mut add), Ok(())); + /// assert_eq!(base, expected); + /// assert!(add.is_empty()); + /// ``` + #[trivial] + pub fn append_overwrite( + &mut self, + other: &mut RangeBoundsSet, + ) -> Result<(), TryFromBoundsError> + where + K: TryFromBounds, + { + for range_bounds in + other.remove_overlapping(&(Bound::Unbounded::, Bound::Unbounded)) + { + self.insert_overwrite(range_bounds)?; + } + + return Ok(()); + } /// Splits the set in two at the given `start_bound()`. Returns /// the full or partial `RangeBounds` after the split.