refactored to use a super traits for simpler trait bounds on functions, and updated depedencies

This commit is contained in:
ripytide
2023-12-03 20:03:36 +00:00
parent 969de2ae7c
commit 6eb28f6137
4 changed files with 219 additions and 63 deletions
Generated
+128
View File
@@ -0,0 +1,128 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "btree_monstrousity"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4d0977e9c15f276380f16f2e9594257c258172b23af39ffd2e4cf5971cb38c7"
dependencies = [
"cfg-if",
"rustversion",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "discrete_range_map"
version = "0.5.2"
dependencies = [
"btree_monstrousity",
"either",
"itertools",
"pretty_assertions",
"serde",
]
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]
[[package]]
name = "pretty_assertions"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "proc-macro2"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "serde"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
+11 -4
View File
@@ -17,10 +17,17 @@ keywords = ["data-structures", "map", "data", "library"]
categories = ["data-structures"] categories = ["data-structures"]
[dependencies] [dependencies]
serde = {version = "1.0.188", features = ["derive"]} serde = { version = "1.0.193", features = ["derive"], default-features = false }
btree_monstrousity = {version ="0.0.4", features = ["btree_drain_filter", "btree_cursors"]} btree_monstrousity = { version = "0.0.4", features = [
either = "1.9.0" "btree_drain_filter",
itertools = "0.11.0" "btree_cursors",
], default-features = false }
either = { version = "1.9.0", default-features = false }
itertools = { version = "0.12.0", default-features = false }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"
[features]
default = ["std"]
std = ["either/use_std", "itertools/use_std", "serde/std"]
+66 -43
View File
@@ -87,10 +87,27 @@ pub struct DiscreteRangeMap<I, K, V> {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct OverlapError; pub struct OverlapError;
/// The marker trait for valid point types, a blanket implementation is provided for all types
/// which implement this traits' super-traits so you shouln't need to implement this yourself.
pub trait PointType: Ord + Copy + DiscreteFinite {}
impl<I> PointType for I where I: Ord + Copy + DiscreteFinite {}
/// The marker trait for valid range types, a blanket implementation is provided for all types
/// which implement this traits' super-traits so you shouln't need to implement this yourself.
pub trait RangeType<I>:
InclusiveRange<I> + Copy + From<InclusiveInterval<I>>
{
}
impl<I, K> RangeType<I> for K
where
I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>>,
{
}
impl<I, K, V> DiscreteRangeMap<I, K, V> impl<I, K, V> DiscreteRangeMap<I, K, V>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>>, K: RangeType<I>,
{ {
/// Returns `true` if the given range overlaps any of the /// Returns `true` if the given range overlaps any of the
/// other ranges in the map, and `false` if not. /// other ranges in the map, and `false` if not.
@@ -118,7 +135,7 @@ where
/// ``` /// ```
pub fn overlaps<Q>(&self, range: Q) -> bool pub fn overlaps<Q>(&self, range: Q) -> bool
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -158,7 +175,7 @@ where
range: Q, range: Q,
) -> impl DoubleEndedIterator<Item = (&K, &V)> ) -> impl DoubleEndedIterator<Item = (&K, &V)>
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -206,7 +223,7 @@ where
range: Q, range: Q,
) -> impl DoubleEndedIterator<Item = (&K, &mut V)> ) -> impl DoubleEndedIterator<Item = (&K, &mut V)>
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -371,7 +388,7 @@ where
range: Q, range: Q,
) -> impl Iterator<Item = (K, V)> + '_ ) -> impl Iterator<Item = (K, V)> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -435,7 +452,7 @@ where
range: Q, range: Q,
) -> impl Iterator<Item = (K, V)> + '_ ) -> impl Iterator<Item = (K, V)> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
V: Clone, V: Clone,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -454,11 +471,18 @@ where
.map(|(key, _)| key) .map(|(key, _)| key)
.copied(); .copied();
if let Some(left) = left_overlapping && let Some(right) = right_overlapping && left.start() == right.start() { if let Some(left) = left_overlapping
Either::Left(self.cut_single_overlapping(range, left)) && let Some(right) = right_overlapping
} else { && left.start() == right.start()
Either::Right(self.cut_non_single_overlapping(range, left_overlapping, right_overlapping)) {
} Either::Left(self.cut_single_overlapping(range, left))
} else {
Either::Right(self.cut_non_single_overlapping(
range,
left_overlapping,
right_overlapping,
))
}
} }
fn cut_single_overlapping<Q>( fn cut_single_overlapping<Q>(
&mut self, &mut self,
@@ -466,7 +490,7 @@ where
single_overlapping_range: K, single_overlapping_range: K,
) -> impl Iterator<Item = (K, V)> ) -> impl Iterator<Item = (K, V)>
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
V: Clone, V: Clone,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -494,7 +518,7 @@ where
right_overlapping: Option<K>, right_overlapping: Option<K>,
) -> impl Iterator<Item = (K, V)> + '_ ) -> impl Iterator<Item = (K, V)> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
V: Clone, V: Clone,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -554,7 +578,7 @@ where
value, value,
) )
})) }))
.chain(keeping_after_entry.into_iter()); .chain(keeping_after_entry);
} }
/// Returns an iterator of ranges over all the maximally-sized /// Returns an iterator of ranges over all the maximally-sized
@@ -587,7 +611,7 @@ where
/// ``` /// ```
pub fn gaps<'a, Q>(&'a self, outer_range: Q) -> impl Iterator<Item = K> + '_ pub fn gaps<'a, Q>(&'a self, outer_range: Q) -> impl Iterator<Item = K> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
{ {
invalid_range_panic(outer_range); invalid_range_panic(outer_range);
@@ -648,7 +672,7 @@ where
.map(K::from) .map(K::from)
.into_iter() .into_iter()
.chain(inner_gaps) .chain(inner_gaps)
.chain(trimmed_end_gap.map(K::from).into_iter()); .chain(trimmed_end_gap.map(K::from));
} }
/// Returns `true` if the map covers every point in the given /// Returns `true` if the map covers every point in the given
@@ -678,7 +702,7 @@ where
/// ``` /// ```
pub fn contains_range<Q>(&self, range: Q) -> bool pub fn contains_range<Q>(&self, range: Q) -> bool
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
invalid_range_panic(range); invalid_range_panic(range);
@@ -1397,8 +1421,8 @@ impl<I, K, V> DiscreteRangeMap<I, K, V> {
fn invalid_range_panic<Q, I>(range: Q) fn invalid_range_panic<Q, I>(range: Q)
where where
Q: InclusiveRange<I>, I: PointType,
I: Ord, Q: RangeType<I>,
{ {
if !is_valid_range(range) { if !is_valid_range(range) {
panic!( panic!(
@@ -1409,22 +1433,22 @@ where
fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering
where where
K: InclusiveRange<I>, I: PointType,
I: Ord + DiscreteFinite, K: RangeType<I>,
{ {
|inner_range: &K, new_range: &K| new_range.start().cmp(&inner_range.start()) |inner_range: &K, new_range: &K| new_range.start().cmp(&inner_range.start())
} }
fn overlapping_comp<I, K>(point: I) -> impl FnMut(&K) -> Ordering fn overlapping_comp<I, K>(point: I) -> impl FnMut(&K) -> Ordering
where where
I: Ord + Copy, I: PointType,
K: InclusiveRange<I> + Copy, K: RangeType<I>,
{ {
move |inner_range: &K| cmp_point_with_range(point, *inner_range) move |inner_range: &K| cmp_point_with_range(point, *inner_range)
} }
fn touching_start_comp<I, K>(start: I) -> impl FnMut(&K) -> Ordering fn touching_start_comp<I, K>(start: I) -> impl FnMut(&K) -> Ordering
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I>, K: RangeType<I>,
{ {
move |inner_range: &K| match inner_range.end().up() { move |inner_range: &K| match inner_range.end().up() {
Some(touching_position) => start.cmp(&touching_position), Some(touching_position) => start.cmp(&touching_position),
@@ -1433,8 +1457,8 @@ where
} }
fn touching_end_comp<I, K>(end: I) -> impl FnMut(&K) -> Ordering fn touching_end_comp<I, K>(end: I) -> impl FnMut(&K) -> Ordering
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I>, K: RangeType<I>,
{ {
move |inner_range: &K| match inner_range.start().down() { move |inner_range: &K| match inner_range.start().down() {
Some(touching_position) => end.cmp(&touching_position), Some(touching_position) => end.cmp(&touching_position),
@@ -1449,14 +1473,14 @@ pub trait InclusiveRange<I> {
fn contains(&self, point: I) -> bool fn contains(&self, point: I) -> bool
where where
I: Ord, I: PointType,
{ {
point >= self.start() && point <= self.end() point >= self.start() && point <= self.end()
} }
fn is_valid(&self) -> bool fn is_valid(&self) -> bool
where where
I: Ord, I: PointType,
{ {
self.start() <= self.end() self.start() <= self.end()
} }
@@ -1464,7 +1488,7 @@ pub trait InclusiveRange<I> {
///requires that self comes before other and they don't overlap ///requires that self comes before other and they don't overlap
fn touches_ordered(&self, other: &Self) -> bool fn touches_ordered(&self, other: &Self) -> bool
where where
I: DiscreteFinite + Ord, I: PointType,
{ {
self.end() == other.start().down().unwrap() self.end() == other.start().down().unwrap()
} }
@@ -1472,7 +1496,7 @@ pub trait InclusiveRange<I> {
///requires that self comes before other ///requires that self comes before other
fn overlaps_ordered(&self, other: &Self) -> bool fn overlaps_ordered(&self, other: &Self) -> bool
where where
I: DiscreteFinite + Ord, I: PointType,
{ {
self.contains(other.start()) || self.contains(other.end()) self.contains(other.start()) || self.contains(other.end())
} }
@@ -1548,8 +1572,8 @@ where
impl<'de, I, K, V> Deserialize<'de> for DiscreteRangeMap<I, K, V> impl<'de, I, K, V> Deserialize<'de> for DiscreteRangeMap<I, K, V>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>> + Deserialize<'de>, K: RangeType<I> + Deserialize<'de>,
V: Deserialize<'de>, V: Deserialize<'de>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -1572,8 +1596,8 @@ struct DiscreteRangeMapVisitor<I, K, V> {
impl<'de, I, K, V> Visitor<'de> for DiscreteRangeMapVisitor<I, K, V> impl<'de, I, K, V> Visitor<'de> for DiscreteRangeMapVisitor<I, K, V>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>> + Deserialize<'de>, K: RangeType<I> + Deserialize<'de>,
V: Deserialize<'de>, V: Deserialize<'de>,
{ {
type Value = DiscreteRangeMap<I, K, V>; type Value = DiscreteRangeMap<I, K, V>;
@@ -1605,9 +1629,9 @@ mod tests {
//only every other number to allow mathematical_overlapping_definition //only every other number to allow mathematical_overlapping_definition
//to test between bounds in finite using smaller intervalled finite //to test between bounds in finite using smaller intervalled finite
pub(crate) const NUMBERS: &'static [i8] = &[2, 4, 6, 8, 10]; pub(crate) const NUMBERS: &[i8] = &[2, 4, 6, 8, 10];
//go a bit around on either side to compensate for Unbounded //go a bit around on either side to compensate for Unbounded
pub(crate) const NUMBERS_DOMAIN: &'static [i8] = pub(crate) const NUMBERS_DOMAIN: &[i8] =
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
fn basic() -> DiscreteRangeMap<i8, InclusiveInterval<i8>, bool> { fn basic() -> DiscreteRangeMap<i8, InclusiveInterval<i8>, bool> {
@@ -1728,12 +1752,11 @@ mod tests {
expected_overlapping.push(inside_range2); expected_overlapping.push(inside_range2);
} }
//make our expected_overlapping the correct order //make our expected_overlapping the correct order
if expected_overlapping.len() > 1 { if expected_overlapping.len() > 1
if expected_overlapping[0].start() && expected_overlapping[0].start()
> expected_overlapping[1].start() > expected_overlapping[1].start()
{ {
expected_overlapping.swap(0, 1); expected_overlapping.swap(0, 1);
}
} }
let overlapping = map let overlapping = map
+14 -16
View File
@@ -5,11 +5,9 @@ use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq; use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::discrete_finite::DiscreteFinite;
use crate::discrete_range_map::{ use crate::discrete_range_map::{
InclusiveRange, IntoIter as DiscreteRangeMapIntoIter, IntoIter as DiscreteRangeMapIntoIter, PointType, RangeType,
}; };
use crate::interval::InclusiveInterval;
use crate::{DiscreteRangeMap, OverlapError}; use crate::{DiscreteRangeMap, OverlapError};
/// An ordered set of non-overlapping ranges based on [`DiscreteRangeMap`]. /// An ordered set of non-overlapping ranges based on [`DiscreteRangeMap`].
@@ -30,13 +28,13 @@ pub struct DiscreteRangeSet<I, K> {
impl<I, K> DiscreteRangeSet<I, K> impl<I, K> DiscreteRangeSet<I, K>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>>, K: RangeType<I>,
{ {
/// See [`DiscreteRangeMap::overlaps()`] for more details. /// See [`DiscreteRangeMap::overlaps()`] for more details.
pub fn overlaps<Q>(&self, range: Q) -> bool pub fn overlaps<Q>(&self, range: Q) -> bool
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
self.inner.overlaps(range) self.inner.overlaps(range)
} }
@@ -46,7 +44,7 @@ where
range: Q, range: Q,
) -> impl DoubleEndedIterator<Item = &K> ) -> impl DoubleEndedIterator<Item = &K>
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
self.inner.overlapping(range).map(first) self.inner.overlapping(range).map(first)
} }
@@ -64,28 +62,28 @@ where
range: Q, range: Q,
) -> impl Iterator<Item = K> + '_ ) -> impl Iterator<Item = K> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
{ {
self.inner.remove_overlapping(range).map(first) self.inner.remove_overlapping(range).map(first)
} }
/// See [`DiscreteRangeMap::cut()`] for more details. /// See [`DiscreteRangeMap::cut()`] for more details.
pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = K> + '_ pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = K> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
{ {
self.inner.cut(range).map(first) self.inner.cut(range).map(first)
} }
/// See [`DiscreteRangeMap::gaps()`] for more details. /// See [`DiscreteRangeMap::gaps()`] for more details.
pub fn gaps<'a, Q>(&'a self, range: Q) -> impl Iterator<Item = K> + '_ pub fn gaps<'a, Q>(&'a self, range: Q) -> impl Iterator<Item = K> + '_
where where
Q: InclusiveRange<I> + Copy + 'a, Q: RangeType<I> + 'a,
{ {
self.inner.gaps(range) self.inner.gaps(range)
} }
/// See [`DiscreteRangeMap::contains_range()`] for more details. /// See [`DiscreteRangeMap::contains_range()`] for more details.
pub fn contains_range<Q>(&self, range: Q) -> bool pub fn contains_range<Q>(&self, range: Q) -> bool
where where
Q: InclusiveRange<I> + Copy, Q: RangeType<I>,
{ {
self.inner.contains_range(range) self.inner.contains_range(range)
} }
@@ -200,7 +198,7 @@ impl<I, K> Iterator for IntoIter<I, K> {
impl<I, K> Default for DiscreteRangeSet<I, K> impl<I, K> Default for DiscreteRangeSet<I, K>
where where
I: PartialOrd, I: PointType,
{ {
fn default() -> Self { fn default() -> Self {
DiscreteRangeSet { DiscreteRangeSet {
@@ -227,8 +225,8 @@ where
impl<'de, I, K> Deserialize<'de> for DiscreteRangeSet<I, K> impl<'de, I, K> Deserialize<'de> for DiscreteRangeSet<I, K>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>> + Deserialize<'de>, K: RangeType<I> + Deserialize<'de>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -248,8 +246,8 @@ struct DiscreteRangeSetVisitor<I, K> {
impl<'de, I, K> Visitor<'de> for DiscreteRangeSetVisitor<I, K> impl<'de, I, K> Visitor<'de> for DiscreteRangeSetVisitor<I, K>
where where
I: Ord + Copy + DiscreteFinite, I: PointType,
K: InclusiveRange<I> + Copy + From<InclusiveInterval<I>> + Deserialize<'de>, K: RangeType<I> + Deserialize<'de>,
{ {
type Value = DiscreteRangeSet<I, K>; type Value = DiscreteRangeSet<I, K>;