refatored discreteBoundOrd to use DiscreteBounds

This commit is contained in:
ripytide 2023-04-20 15:16:02 +01:00
parent f1a588eb9c
commit 0dd08da2bd
No known key found for this signature in database
GPG Key ID: B2629F9EC7C2FE8C
3 changed files with 46 additions and 181 deletions

View File

@ -18,10 +18,10 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
*/
use std::cmp::Ordering;
use std::ops::Bound;
use serde::{Deserialize, Serialize};
use crate::discrete_bounds::DiscreteBound;
use crate::stepable::Stepable;
/// An newtype of [`Bound`] to implement [`Ord`] on types that
@ -30,33 +30,22 @@ use crate::stepable::Stepable;
/// [`Step`]: std::iter::Step
#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) enum DiscreteBoundOrd<T> {
/// Mirror of [`Bound::Included`]
/// There is no need for different Start and End variations as the
/// Ord implementations are equivalent.
Included(T),
/// [`Bound::Excluded`] specific to Start bounds.
StartExcluded(T),
/// [`Bound::Unbounded`] specific to Start bounds.
StartUnbounded,
/// [`Bound::Excluded`] specific to End bounds.
EndExcluded(T),
/// [`Bound::Unbounded`] specific to End bounds.
EndUnbounded,
}
impl<T> DiscreteBoundOrd<T> {
pub(crate) fn start(bound: Bound<T>) -> Self {
match bound {
Bound::Included(point) => DiscreteBoundOrd::Included(point),
Bound::Excluded(point) => DiscreteBoundOrd::StartExcluded(point),
Bound::Unbounded => DiscreteBoundOrd::StartUnbounded,
impl<I> DiscreteBoundOrd<I> {
pub(crate) fn start(discrete_bound: DiscreteBound<I>) -> Self {
match discrete_bound {
DiscreteBound::Included(point) => DiscreteBoundOrd::Included(point),
DiscreteBound::Unbounded => DiscreteBoundOrd::StartUnbounded,
}
}
pub(crate) fn end(bound: Bound<T>) -> Self {
match bound {
Bound::Included(point) => DiscreteBoundOrd::Included(point),
Bound::Excluded(point) => DiscreteBoundOrd::EndExcluded(point),
Bound::Unbounded => DiscreteBoundOrd::EndUnbounded,
pub(crate) fn end(discrete_bound: DiscreteBound<I>) -> Self {
match discrete_bound {
DiscreteBound::Included(point) => DiscreteBoundOrd::Included(point),
DiscreteBound::Unbounded => DiscreteBoundOrd::EndUnbounded,
}
}
}
@ -69,32 +58,14 @@ where
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(DiscreteBoundOrd::Included(start1), DiscreteBoundOrd::Included(start2)) => start1.cmp(start2),
(DiscreteBoundOrd::Included(start1), DiscreteBoundOrd::StartExcluded(start2)) => start1.cmp(&start2.up().unwrap()),
(DiscreteBoundOrd::Included(start1), DiscreteBoundOrd::EndExcluded(start2)) => start1.cmp(&start2.down().unwrap()),
(DiscreteBoundOrd::Included(_), DiscreteBoundOrd::EndUnbounded) => Ordering::Less,
(DiscreteBoundOrd::Included(_), DiscreteBoundOrd::StartUnbounded) => Ordering::Greater,
(DiscreteBoundOrd::StartExcluded(start1), DiscreteBoundOrd::StartExcluded(start2)) => start1.cmp(start2),
(DiscreteBoundOrd::StartExcluded(start1), DiscreteBoundOrd::Included(start2)) => start1.up().unwrap().cmp(start2),
(DiscreteBoundOrd::StartExcluded(start1), DiscreteBoundOrd::EndExcluded(start2)) => start1.up().unwrap().cmp(&start2.down().unwrap()),
(DiscreteBoundOrd::StartExcluded(_), DiscreteBoundOrd::StartUnbounded) => Ordering::Greater,
(DiscreteBoundOrd::StartExcluded(_), DiscreteBoundOrd::EndUnbounded) => Ordering::Less,
(DiscreteBoundOrd::StartUnbounded, DiscreteBoundOrd::Included(_)) => Ordering::Less,
(DiscreteBoundOrd::StartUnbounded, DiscreteBoundOrd::StartExcluded(_)) => Ordering::Less,
(DiscreteBoundOrd::StartUnbounded, DiscreteBoundOrd::EndExcluded(_)) => Ordering::Less,
(DiscreteBoundOrd::StartUnbounded, DiscreteBoundOrd::StartUnbounded) => Ordering::Equal,
(DiscreteBoundOrd::StartUnbounded, DiscreteBoundOrd::EndUnbounded) => Ordering::Less,
(DiscreteBoundOrd::EndExcluded(start1), DiscreteBoundOrd::EndExcluded(start2)) => start1.cmp(start2),
(DiscreteBoundOrd::EndExcluded(start1), DiscreteBoundOrd::Included(start2)) => start1.down().unwrap().cmp(&start2),
(DiscreteBoundOrd::EndExcluded(start1), DiscreteBoundOrd::StartExcluded(start2)) => start1.down().unwrap().cmp(&start2.up().unwrap()),
(DiscreteBoundOrd::EndExcluded(_), DiscreteBoundOrd::StartUnbounded) => Ordering::Greater,
(DiscreteBoundOrd::EndExcluded(_), DiscreteBoundOrd::EndUnbounded) => Ordering::Less,
(DiscreteBoundOrd::EndUnbounded, DiscreteBoundOrd::Included(_)) => Ordering::Greater,
(DiscreteBoundOrd::EndUnbounded, DiscreteBoundOrd::StartExcluded(_)) => Ordering::Greater,
(DiscreteBoundOrd::EndUnbounded, DiscreteBoundOrd::EndExcluded(_)) => Ordering::Greater,
(DiscreteBoundOrd::EndUnbounded, DiscreteBoundOrd::EndUnbounded) => Ordering::Equal,
(DiscreteBoundOrd::EndUnbounded, DiscreteBoundOrd::StartUnbounded) => Ordering::Greater,
}
@ -121,18 +92,6 @@ where
impl<T> Eq for DiscreteBoundOrd<T> where T: Ord + Stepable {}
impl<T> From<DiscreteBoundOrd<T>> for Bound<T> {
fn from(start_bound: DiscreteBoundOrd<T>) -> Bound<T> {
match start_bound {
DiscreteBoundOrd::Included(point) => Bound::Included(point),
DiscreteBoundOrd::StartExcluded(point) => Bound::Excluded(point),
DiscreteBoundOrd::StartUnbounded => Bound::Unbounded,
DiscreteBoundOrd::EndExcluded(point) => Bound::Excluded(point),
DiscreteBoundOrd::EndUnbounded => Bound::Unbounded,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -146,76 +105,12 @@ mod tests {
assert!(DiscreteBoundOrd::Included(0) < DiscreteBoundOrd::Included(2));
assert!(DiscreteBoundOrd::Included(2) > DiscreteBoundOrd::Included(0));
assert!(
DiscreteBoundOrd::Included(2) < DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::Included(0) < DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::Included(2) > DiscreteBoundOrd::StartExcluded(0)
);
assert!(
DiscreteBoundOrd::Included(2) > DiscreteBoundOrd::StartUnbounded
);
assert!(
DiscreteBoundOrd::Included(2) > DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::Included(0) < DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::Included(2) > DiscreteBoundOrd::EndExcluded(0)
);
assert!(DiscreteBoundOrd::Included(2) < DiscreteBoundOrd::EndUnbounded);
//StartExcluded
assert!(
DiscreteBoundOrd::StartExcluded(2)
== DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
<= DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
>= DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(0)
< DiscreteBoundOrd::StartExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
> DiscreteBoundOrd::StartExcluded(0)
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
> DiscreteBoundOrd::StartUnbounded
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
> DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(2)
> DiscreteBoundOrd::EndExcluded(0)
);
assert!(
DiscreteBoundOrd::StartExcluded(0)
< DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::StartExcluded(2) < DiscreteBoundOrd::EndUnbounded
);
//StartUnbounded
assert!(
DiscreteBoundOrd::StartUnbounded::<i8>
@ -230,35 +125,11 @@ mod tests {
>= DiscreteBoundOrd::StartUnbounded
);
assert!(
DiscreteBoundOrd::StartUnbounded < DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::StartUnbounded::<i8>
< DiscreteBoundOrd::EndUnbounded
);
//EndExcluded
assert!(
DiscreteBoundOrd::EndExcluded(2)
== DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::EndExcluded(2)
<= DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::EndExcluded(2)
>= DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::EndExcluded(0) < DiscreteBoundOrd::EndExcluded(2)
);
assert!(
DiscreteBoundOrd::EndExcluded(2) > DiscreteBoundOrd::EndExcluded(0)
);
//EndUnbounded
assert!(
DiscreteBoundOrd::EndUnbounded::<i8>

View File

@ -35,7 +35,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::bound_ord::DiscreteBoundOrd;
use crate::discrete_bounds::DiscreteBounds;
use crate::utils::{
cmp_range_with_discrete_bound_ord, cut_range, flip_bound, is_valid_range, overlaps,
cmp_range_with_discrete_bound_ord, cut_range, flip_bound, is_valid_range,
overlaps,
};
/// An ordered map of non-overlapping ranges based on [`BTreeMap`].
@ -791,7 +792,7 @@ where
>
where
Q: NiceRange<I>,
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
V: Clone,
{
invalid_range_panic(range);
@ -831,7 +832,7 @@ where
>
where
Q: NiceRange<I> + 'a,
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
V: Clone,
{
invalid_range_panic(range);
@ -1087,7 +1088,7 @@ where
remove_end: R2,
) -> Result<K, TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
G1: FnOnce(&Self, &V) -> Option<K>,
G2: FnOnce(&Self, &V) -> Option<K>,
R1: FnOnce(&mut Self, &V),
@ -1187,7 +1188,7 @@ where
value: V,
) -> Result<K, OverlapOrTryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
invalid_range_panic(range);
@ -1286,7 +1287,7 @@ where
value: V,
) -> Result<K, OverlapOrTryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
V: Eq,
{
invalid_range_panic(range);
@ -1396,7 +1397,7 @@ where
value: V,
) -> Result<K, TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
invalid_range_panic(range);
@ -1483,7 +1484,7 @@ where
value: V,
) -> Result<K, TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
invalid_range_panic(range);
@ -1560,7 +1561,7 @@ where
value: V,
) -> Result<(), TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
V: Clone,
{
invalid_range_panic(range);
@ -1679,7 +1680,10 @@ where
K: NiceRange<I>,
{
move |inner_range: &K| {
cmp_range_with_discrete_bound_ord(*inner_range, DiscreteBoundOrd::start(start))
cmp_range_with_discrete_bound_ord(
*inner_range,
DiscreteBoundOrd::start(start),
)
}
}
fn overlapping_end_comp<I, K>(end: Bound<I>) -> impl FnMut(&K) -> Ordering
@ -1688,7 +1692,10 @@ where
K: NiceRange<I>,
{
move |inner_range: &K| {
cmp_range_with_discrete_bound_ord(*inner_range, DiscreteBoundOrd::end(end))
cmp_range_with_discrete_bound_ord(
*inner_range,
DiscreteBoundOrd::end(end),
)
}
}
fn touching_start_comp<I, K>(start: Bound<I>) -> impl FnMut(&K) -> Ordering
@ -1707,7 +1714,8 @@ where
}
(end, start) => {
let normal_result = DiscreteBoundOrd::start(start).cmp(&DiscreteBoundOrd::end(end));
let normal_result =
DiscreteBoundOrd::start(start).cmp(&DiscreteBoundOrd::end(end));
//we overide any Equals to a random non-Equal since we
//don't want non-touching matches
@ -1734,8 +1742,8 @@ where
}
(end, _start) => {
let normal_result =
DiscreteBoundOrd::end(end).cmp(&DiscreteBoundOrd::start(inner_range.start()));
let normal_result = DiscreteBoundOrd::end(end)
.cmp(&DiscreteBoundOrd::start(inner_range.start()));
//we overide any Equals to a random non-Equal since we
//don't want non-touching matches
@ -1938,22 +1946,6 @@ mod tests {
}
}
}
impl TryFromBounds<i8> for MultiBounds {
fn try_from_bounds(
start_bound: Bound<i8>,
end_bound: Bound<i8>,
) -> Result<Self, TryFromBoundsError> {
match (start_bound, end_bound) {
(Bound::Included(start), Bound::Included(end)) => {
Ok(mii(start, end))
}
(Bound::Excluded(start), Bound::Excluded(end)) => {
Ok(mee(start, end))
}
_ => Err(TryFromBoundsError),
}
}
}
#[test]
fn insert_strict_tests() {
@ -2078,8 +2070,9 @@ mod tests {
//make our expected_overlapping the correct order
if expected_overlapping.len() > 1 {
if DiscreteBoundOrd::start(expected_overlapping[0].start())
> DiscreteBoundOrd::start(expected_overlapping[1].start())
{
> DiscreteBoundOrd::start(
expected_overlapping[1].start(),
) {
expected_overlapping.swap(0, 1);
}
}
@ -2228,7 +2221,7 @@ mod tests {
after: Option<[(K, V); N]>,
) where
I: Ord + Debug + Copy,
K: NiceRange<I> + TryFromBounds<I> + PartialEq + Debug,
K: NiceRange<I> + TryFrom<DiscreteBounds<I>> + PartialEq + Debug,
Q: NiceRange<I>,
V: PartialEq + Debug + Clone,
{
@ -2374,7 +2367,7 @@ mod tests {
after: Option<[(K, V); N]>,
) where
I: Ord + Debug + Copy,
K: NiceRange<I> + TryFromBounds<I> + PartialEq + Debug,
K: NiceRange<I> + TryFrom<DiscreteBounds<I>> + PartialEq + Debug,
V: PartialEq + Debug + Clone,
{
let clone = before.clone();
@ -2497,7 +2490,7 @@ mod tests {
after: Option<[(K, V); N]>,
) where
I: Ord + Debug + Copy,
K: NiceRange<I> + TryFromBounds<I> + PartialEq + Debug,
K: NiceRange<I> + TryFrom<DiscreteBounds<I>> + PartialEq + Debug,
V: Eq + Debug + Clone,
{
let clone = before.clone();
@ -2605,7 +2598,7 @@ mod tests {
after: Option<[(K, V); N]>,
) where
I: Ord + Debug + Copy,
K: NiceRange<I> + TryFromBounds<I> + PartialEq + Debug,
K: NiceRange<I> + TryFrom<DiscreteBounds<I>> + PartialEq + Debug,
V: PartialEq + Debug + Clone,
{
let clone = before.clone();
@ -2739,7 +2732,7 @@ mod tests {
after: Option<[(K, V); N]>,
) where
I: Ord + Debug + Copy,
K: NiceRange<I> + TryFromBounds<I> + PartialEq + Debug,
K: NiceRange<I> + TryFrom<DiscreteBounds<I>> + PartialEq + Debug,
V: PartialEq + Debug + Clone,
{
let clone = before.clone();

View File

@ -6,6 +6,7 @@ use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::discrete_bounds::DiscreteBounds;
use crate::range_bounds_map::{IntoIter as RangeBoundsMapIntoIter, NiceRange};
use crate::{
OverlapError, OverlapOrTryFromBoundsError, RangeBoundsMap,
@ -98,7 +99,7 @@ where
>
where
Q: NiceRange<I> + 'a,
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
self.inner.cut(range).map(|x| x.map(first))
}
@ -129,7 +130,7 @@ where
range: K,
) -> Result<K, OverlapOrTryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
self.inner.insert_merge_touching(range, ())
}
@ -139,7 +140,7 @@ where
range: K,
) -> Result<K, TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
self.inner.insert_merge_overlapping(range, ())
}
@ -149,7 +150,7 @@ where
range: K,
) -> Result<K, TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
self.inner.insert_merge_touching_or_overlapping(range, ())
}
@ -159,7 +160,7 @@ where
range: K,
) -> Result<(), TryFromBoundsError>
where
K: TryFromBounds<I>,
K: TryFrom<DiscreteBounds<I>>,
{
self.inner.insert_overwrite(range, ())
}