migrate doc examples to use into_iter and re-implement IntoIterator on set.rs and map.rs
This commit is contained in:
+2
-2
@@ -235,12 +235,12 @@ pub(crate) mod helpers;
|
||||
pub mod test_ranges;
|
||||
|
||||
pub mod range_bounds_map;
|
||||
//pub mod range_bounds_set;
|
||||
pub mod range_bounds_set;
|
||||
pub mod try_from_bounds;
|
||||
|
||||
pub use crate::range_bounds_map::{
|
||||
OverlapError, OverlapOrTryFromBoundsError, RangeBoundsMap,
|
||||
TryFromBoundsError,
|
||||
};
|
||||
//pub use crate::range_bounds_set::RangeBoundsSet;
|
||||
pub use crate::range_bounds_set::RangeBoundsSet;
|
||||
pub use crate::try_from_bounds::TryFromBounds;
|
||||
|
||||
+89
-28
@@ -23,7 +23,9 @@ use std::iter::once;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use btree_monstrousity::btree_map::SearchBoundCustom;
|
||||
use btree_monstrousity::btree_map::{
|
||||
IntoIter as BTreeMapIntoIter, SearchBoundCustom,
|
||||
};
|
||||
use btree_monstrousity::BTreeMap;
|
||||
use either::Either;
|
||||
use itertools::Itertools;
|
||||
@@ -288,10 +290,10 @@ where
|
||||
/// ```
|
||||
/// use std::ops::Range;
|
||||
///
|
||||
/// use range_bounds_map::test_ranges::TestBounds;
|
||||
/// use range_bounds_map::test_ranges::AnyRange;
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let map: RangeBoundsMap<i8, TestBounds, bool> =
|
||||
/// let map: RangeBoundsMap<i8, AnyRange, bool> =
|
||||
/// RangeBoundsMap::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
@@ -365,6 +367,8 @@ where
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
self.overlapping(range).next().is_some()
|
||||
}
|
||||
|
||||
@@ -405,9 +409,7 @@ where
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
if !is_valid_range(range) {
|
||||
panic!("Invalid RangeBounds!");
|
||||
}
|
||||
invalid_range_panic(range);
|
||||
|
||||
let lower_comp = overlapping_start_comp(range.start());
|
||||
let upper_comp = overlapping_end_comp(range.end());
|
||||
@@ -569,8 +571,8 @@ where
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [(&(ie(8, 100)), &false)]
|
||||
/// map.into_iter().collect::<Vec<_>>(),
|
||||
/// [(ie(8, 100), false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn remove_overlapping<'a, Q>(
|
||||
@@ -580,6 +582,8 @@ where
|
||||
where
|
||||
Q: NiceRange<I> + 'a,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
//optimisation, switch to BTreeMap::drain_range if it ever gets
|
||||
//implemented
|
||||
return self
|
||||
@@ -652,6 +656,8 @@ where
|
||||
K: TryFromBounds<I>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
let start_comp = overlapping_start_comp(range.start());
|
||||
let end_comp = overlapping_end_comp(range.end());
|
||||
|
||||
@@ -666,7 +672,7 @@ where
|
||||
Ok(Either::Right(self.cut_non_single_overlapping(range, left_overlapping, right_overlapping)?))
|
||||
}
|
||||
}
|
||||
pub fn cut_single_overlapping<Q>(
|
||||
fn cut_single_overlapping<Q>(
|
||||
&mut self,
|
||||
range: Q,
|
||||
single_overlapping_range: K,
|
||||
@@ -679,6 +685,8 @@ where
|
||||
K: TryFromBounds<I>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
let cut_result = cut_range(single_overlapping_range, range);
|
||||
let returning_before_cut = match cut_result.before_cut {
|
||||
Some((start, end)) => Some(K::try_from_bounds(start, end)?),
|
||||
@@ -703,7 +711,7 @@ where
|
||||
|
||||
Ok(once((cut_result.inside_cut.unwrap(), value)))
|
||||
}
|
||||
pub fn cut_non_single_overlapping<'a, Q>(
|
||||
fn cut_non_single_overlapping<'a, Q>(
|
||||
&'a mut self,
|
||||
range: Q,
|
||||
left_overlapping: Option<K>,
|
||||
@@ -717,6 +725,8 @@ where
|
||||
K: TryFromBounds<I>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
let before_config = match left_overlapping {
|
||||
Some(before) => {
|
||||
let cut_result = cut_range(before, range);
|
||||
@@ -832,6 +842,8 @@ where
|
||||
where
|
||||
Q: NiceRange<I> + 'a,
|
||||
{
|
||||
invalid_range_panic(outer_range);
|
||||
|
||||
// I'm in love with how clean/mindblowing this entire function is
|
||||
let overlapping = self
|
||||
.overlapping(outer_range)
|
||||
@@ -907,6 +919,8 @@ where
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
// Soooo clean and mathematical 🥰!
|
||||
self.gaps(range).next().is_none()
|
||||
}
|
||||
@@ -941,6 +955,8 @@ where
|
||||
range: K,
|
||||
value: V,
|
||||
) -> Result<(), OverlapError> {
|
||||
invalid_range_panic(range);
|
||||
|
||||
if self.overlaps(range) {
|
||||
return Err(OverlapError);
|
||||
}
|
||||
@@ -969,6 +985,8 @@ where
|
||||
R1: FnOnce(&mut Self),
|
||||
R2: FnOnce(&mut Self),
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
let matching_start = get_start(self);
|
||||
let matching_end = get_end(self);
|
||||
|
||||
@@ -1049,8 +1067,8 @@ where
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [(&ie(1, 6), &true), (&ie(10, 16), &false)]
|
||||
/// map.into_iter().collect::<Vec<_>>(),
|
||||
/// [(ie(1, 6), true), (ie(10, 16), false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_merge_touching(
|
||||
@@ -1061,6 +1079,8 @@ where
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
if self.overlaps(range) {
|
||||
return Err(OverlapOrTryFromBoundsError::Overlap(OverlapError));
|
||||
}
|
||||
@@ -1139,12 +1159,8 @@ where
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [
|
||||
/// (&ie(-4, 1), &true),
|
||||
/// (&ie(1, 8), &true),
|
||||
/// (&ie(10, 16), &false)
|
||||
/// ]
|
||||
/// map.into_iter().collect::<Vec<_>>(),
|
||||
/// [(ie(-4, 1), true), (ie(1, 8), true), (ie(10, 16), false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_merge_overlapping(
|
||||
@@ -1155,6 +1171,8 @@ where
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
@@ -1224,8 +1242,8 @@ where
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [(&ie(-4, 8), &true), (&ie(10, 16), &false)]
|
||||
/// map.into_iter().collect::<Vec<_>>(),
|
||||
/// [(ie(-4, 8), true), (ie(10, 16), false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_merge_touching_or_overlapping(
|
||||
@@ -1236,6 +1254,8 @@ where
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
@@ -1299,12 +1319,8 @@ where
|
||||
/// assert_eq!(map.insert_overwrite(ie(4, 6), true), Ok(()));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [
|
||||
/// (&ie(2, 4), &false),
|
||||
/// (&ie(4, 6), &true),
|
||||
/// (&ie(6, 8), &false)
|
||||
/// ]
|
||||
/// map.into_iter().collect::<Vec<_>>(),
|
||||
/// [(ie(2, 4), false), (ie(4, 6), true), (ie(6, 8), false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_overwrite(
|
||||
@@ -1316,6 +1332,8 @@ where
|
||||
K: TryFromBounds<I>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
let _ = self.cut(range)?;
|
||||
self.insert_unchecked(range, value);
|
||||
|
||||
@@ -1377,6 +1395,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Helper Functions ==========================
|
||||
|
||||
fn invalid_range_panic<Q, I>(range: Q)
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
I: Ord,
|
||||
{
|
||||
if !is_valid_range(range) {
|
||||
panic!("Invalid RangeBounds!");
|
||||
}
|
||||
}
|
||||
|
||||
fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering
|
||||
where
|
||||
K: NiceRange<I>,
|
||||
@@ -1479,6 +1509,38 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Trait Impls ==========================
|
||||
|
||||
impl<I, K, V> IntoIterator for RangeBoundsMap<I, K, V>
|
||||
{
|
||||
type Item = (K, V);
|
||||
type IntoIter = IntoIter<I, K, V>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
return IntoIter {
|
||||
inner: self.inner.into_iter(),
|
||||
phantom: PhantomData,
|
||||
};
|
||||
}
|
||||
}
|
||||
/// An owning iterator over the entries of a [`RangeBoundsMap`].
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on
|
||||
/// [`RangeBoundsMap`] (provided by the [`IntoIterator`] trait). See
|
||||
/// its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
pub struct IntoIter<I, K, V> {
|
||||
inner: BTreeMapIntoIter<K, V>,
|
||||
phantom: PhantomData<I>,
|
||||
}
|
||||
impl<I, K, V> Iterator for IntoIter<I, K, V> {
|
||||
type Item = (K, V);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::ops::Bound;
|
||||
@@ -2358,8 +2420,7 @@ mod tests {
|
||||
|
||||
// Test Helper Functions
|
||||
//======================
|
||||
fn all_non_overlapping_test_bound_entries() -> Vec<(AnyRange, AnyRange)>
|
||||
{
|
||||
fn all_non_overlapping_test_bound_entries() -> Vec<(AnyRange, AnyRange)> {
|
||||
let mut output = Vec::new();
|
||||
for test_bounds1 in all_valid_test_bounds() {
|
||||
for test_bounds2 in all_valid_test_bounds() {
|
||||
|
||||
+203
-1
@@ -1,4 +1,206 @@
|
||||
#[trivial]
|
||||
use std::ops::Bound;
|
||||
|
||||
use crate::range_bounds_map::{IntoIter as RangeBoundsMapIntoIter, NiceRange};
|
||||
use crate::{
|
||||
OverlapError, OverlapOrTryFromBoundsError, RangeBoundsMap, TryFromBounds,
|
||||
TryFromBoundsError,
|
||||
};
|
||||
|
||||
/// An ordered set of non-overlapping [`RangeBounds`] based on [`RangeBoundsMap`].
|
||||
///
|
||||
/// `I` is the generic type parameter for the [`Ord`] type the `K`
|
||||
/// type is [`RangeBounds`] over.
|
||||
///
|
||||
/// `K` is the generic type parameter for the [`RangeBounds`]
|
||||
/// implementing type in the set.
|
||||
///
|
||||
/// See [`RangeBoundsMap`] for more details.
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
pub struct RangeBoundsSet<I, K> {
|
||||
inner: RangeBoundsMap<I, K, ()>,
|
||||
}
|
||||
|
||||
impl<I, K> RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord + Copy,
|
||||
K: NiceRange<I>,
|
||||
{
|
||||
/// See [`RangeBoundsMap::new()`] for more details.
|
||||
pub fn new() -> Self {
|
||||
RangeBoundsSet {
|
||||
inner: RangeBoundsMap::new(),
|
||||
}
|
||||
}
|
||||
/// See [`RangeBoundsMap::len()`] for more details.
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
/// See [`RangeBoundsMap::is_empty()`] for more details.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
/// See [`RangeBoundsMap::overlaps()`] for more details.
|
||||
pub fn overlaps<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
self.inner.overlaps(range)
|
||||
}
|
||||
/// See [`RangeBoundsMap::overlapping()`] for more details.
|
||||
pub fn overlapping<Q>(
|
||||
&self,
|
||||
range: Q,
|
||||
) -> impl DoubleEndedIterator<Item = &K>
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
self.inner.overlapping(range).map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::contains_point()`] for more details.
|
||||
pub fn contains_point(&self, point: I) -> bool {
|
||||
self.inner.contains_point(point)
|
||||
}
|
||||
/// See [`RangeBoundsMap::iter()`] for more details.
|
||||
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &K> {
|
||||
self.inner.iter().map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::remove_overlapping()`] for more details.
|
||||
pub fn remove_overlapping<'a, Q>(
|
||||
&'a mut self,
|
||||
range: Q,
|
||||
) -> impl Iterator<Item = K> + '_
|
||||
where
|
||||
Q: NiceRange<I> + 'a,
|
||||
{
|
||||
self.inner.remove_overlapping(range).map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::cut()`] for more details.
|
||||
pub fn cut<'a, Q>(
|
||||
&'a mut self,
|
||||
range: Q,
|
||||
) -> Result<
|
||||
impl Iterator<Item = (Bound<I>, Bound<I>)> + '_,
|
||||
TryFromBoundsError,
|
||||
>
|
||||
where
|
||||
Q: NiceRange<I> + 'a,
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.inner.cut(range).map(|x| x.map(first))
|
||||
}
|
||||
/// See [`RangeBoundsMap::gaps()`] for more details.
|
||||
pub fn gaps<'a, Q>(
|
||||
&'a self,
|
||||
range: Q,
|
||||
) -> impl Iterator<Item = (Bound<I>, Bound<I>)> + '_
|
||||
where
|
||||
Q: NiceRange<I> + 'a,
|
||||
{
|
||||
self.inner.gaps(range)
|
||||
}
|
||||
/// See [`RangeBoundsMap::contains_range()`] for more details.
|
||||
pub fn contains_range<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
self.inner.contains_range(range)
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_strict()`] for more details.
|
||||
pub fn insert_strict(&mut self, range: K) -> Result<(), OverlapError> {
|
||||
self.inner.insert_strict(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_touching()`] for more details.
|
||||
pub fn insert_merge_touching(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> Result<K, OverlapOrTryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.inner.insert_merge_touching(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_overlapping()`] for more details.
|
||||
pub fn insert_merge_overlapping(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> Result<K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.inner.insert_merge_overlapping(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_touching_or_overlapping()`] for more details.
|
||||
pub fn insert_merge_touching_or_overlapping(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> Result<K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.inner.insert_merge_touching_or_overlapping(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_overwrite()`] for more details.
|
||||
pub fn insert_overwrite(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> Result<(), TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.inner.insert_overwrite(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::first_entry()`] for more details.
|
||||
pub fn first(&self) -> Option<&K> {
|
||||
self.inner.first_entry().map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::last_entry()`] for more details.
|
||||
pub fn last(&self) -> Option<&K> {
|
||||
self.inner.last_entry().map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::from_slice_strict()`] for more details.
|
||||
pub fn from_slice_strict<const N: usize>(
|
||||
slice: [K; N],
|
||||
) -> Result<RangeBoundsSet<I, K>, OverlapError> {
|
||||
let mut set = RangeBoundsSet::new();
|
||||
for range in slice {
|
||||
set.insert_strict(range)?;
|
||||
}
|
||||
return Ok(set);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper Functions ==========================
|
||||
|
||||
fn first<A, B>((a, _): (A, B)) -> A {
|
||||
a
|
||||
}
|
||||
|
||||
// Trait Impls ==========================
|
||||
|
||||
impl<I, K> IntoIterator for RangeBoundsSet<I, K> {
|
||||
type Item = K;
|
||||
type IntoIter = IntoIter<I, K>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
return IntoIter {
|
||||
inner: self.inner.into_iter(),
|
||||
};
|
||||
}
|
||||
}
|
||||
/// An owning iterator over the entries of a [`RangeBoundsSet`].
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on
|
||||
/// [`RangeBoundsSet`] (provided by the [`IntoIterator`] trait). See
|
||||
/// its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
pub struct IntoIter<I, K> {
|
||||
inner: RangeBoundsMapIntoIter<I, K, ()>,
|
||||
}
|
||||
impl<I, K> Iterator for IntoIter<I, K> {
|
||||
type Item = K;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next().map(first)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user