reworked the common 4 trait impls and bounds and re-added a startBoundOrd wrapper
This commit is contained in:
+39
-38
@@ -34,7 +34,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
|
||||
/// [`comparator`]: https://stackoverflow.com/q/34028324
|
||||
/// [`Cursor`]: https://github.com/rust-lang/rfcs/issues/1778
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub(crate) enum BoundOrd<T> {
|
||||
/// Mirror of [`Bound::Included`]
|
||||
/// There is no need for different Start and End variations as the
|
||||
@@ -69,49 +69,60 @@ impl<T> BoundOrd<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for BoundOrd<T> where T: PartialEq {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl<T> PartialOrd for BoundOrd<T>
|
||||
impl<T> Ord for BoundOrd<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
T: Ord,
|
||||
{
|
||||
#[rustfmt::skip]
|
||||
#[tested]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(BoundOrd::Included(start1), BoundOrd::Included(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::Included(start1), BoundOrd::StartExcluded(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::Included(start1), BoundOrd::EndExcluded(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::Included(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
(BoundOrd::Included(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
fn cmp(&self, other: &Self) ->Ordering {
|
||||
match (self, other) {
|
||||
(BoundOrd::Included(start1), BoundOrd::Included(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::Included(start1), BoundOrd::StartExcluded(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::Included(start1), BoundOrd::EndExcluded(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::Included(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
(BoundOrd::Included(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::StartExcluded(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::Included(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::EndExcluded(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::StartExcluded(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
(BoundOrd::StartExcluded(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::StartExcluded(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::Included(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::StartExcluded(start1), BoundOrd::EndExcluded(start2)) => partial_cmp_with_priority(start1, start2, false),
|
||||
(BoundOrd::StartExcluded(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
(BoundOrd::StartExcluded(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
|
||||
(BoundOrd::StartUnbounded, BoundOrd::Included(_)) => Some(Ordering::Less),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::StartExcluded(_)) => Some(Ordering::Less),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::EndExcluded(_)) => Some(Ordering::Less),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::StartUnbounded) => Some(Ordering::Equal),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::StartUnbounded) => Some(Ordering::Equal),
|
||||
(BoundOrd::StartUnbounded, BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::EndExcluded(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::Included(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::StartExcluded(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::EndExcluded(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
(BoundOrd::EndExcluded(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::EndExcluded(start2)) => start1.partial_cmp(start2),
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::Included(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::EndExcluded(start1), BoundOrd::StartExcluded(start2)) => partial_cmp_with_priority(start1, start2, true),
|
||||
(BoundOrd::EndExcluded(_), BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
(BoundOrd::EndExcluded(_), BoundOrd::EndUnbounded) => Some(Ordering::Less),
|
||||
|
||||
(BoundOrd::EndUnbounded, BoundOrd::Included(_)) => Some(Ordering::Greater),
|
||||
(BoundOrd::EndUnbounded, BoundOrd::StartExcluded(_)) => Some(Ordering::Greater),
|
||||
(BoundOrd::EndUnbounded, BoundOrd::EndExcluded(_)) => Some(Ordering::Greater),
|
||||
(BoundOrd::EndUnbounded, BoundOrd::EndUnbounded) => Some(Ordering::Equal),
|
||||
(BoundOrd::EndUnbounded, BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
}
|
||||
(BoundOrd::EndUnbounded, BoundOrd::EndUnbounded) => Some(Ordering::Equal),
|
||||
(BoundOrd::EndUnbounded, BoundOrd::StartUnbounded) => Some(Ordering::Greater),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialOrd for BoundOrd<T> where T: Ord {}
|
||||
|
||||
impl<T> PartialEq for BoundOrd<T>
|
||||
where
|
||||
T: Ord,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.cmp(&other).is_eq()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for BoundOrd<T> where T: Ord {}
|
||||
|
||||
/// If they are equal say the item with priority is larger
|
||||
/// where false means left has priority and true means right.
|
||||
#[parent_tested]
|
||||
@@ -134,16 +145,6 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
impl<T> Ord for BoundOrd<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
#[trivial]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<BoundOrd<T>> for Bound<T> {
|
||||
#[trivial]
|
||||
fn from(start_bound: BoundOrd<T>) -> Bound<T> {
|
||||
|
||||
@@ -228,6 +228,7 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
pub(crate) mod bound_ord;
|
||||
pub mod range_bounds_map;
|
||||
pub mod range_bounds_set;
|
||||
pub(crate) mod start_range_bounds_ord_wrapper;
|
||||
pub mod try_from_bounds;
|
||||
|
||||
pub use crate::range_bounds_map::{
|
||||
|
||||
@@ -32,6 +32,7 @@ use serde::ser::SerializeMap;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::bound_ord::BoundOrd;
|
||||
use crate::start_range_bounds_ord_wrapper::StartRangeBoundsOrdWrapper;
|
||||
use crate::TryFromBounds;
|
||||
|
||||
/// An ordered map of non-overlapping [`RangeBounds`] based on [`BTreeMap`].
|
||||
@@ -126,12 +127,12 @@ use crate::TryFromBounds;
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
/// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RangeBoundsMap<I, K, V>
|
||||
where
|
||||
I: PartialOrd,
|
||||
{
|
||||
starts: BTreeMap<BoundOrd<I>, (K, V)>,
|
||||
inner: BTreeMap<StartRangeBoundsOrdWrapper<I, K>, V>,
|
||||
}
|
||||
|
||||
/// An error type to represent a [`RangeBounds`] overlapping another
|
||||
@@ -2130,10 +2131,11 @@ where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
type Item = (&'a K, &'a V);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (key, value) = self.cursor.value()?;
|
||||
|
||||
if overlaps(self.query_range_bounds, key) {
|
||||
self.cursor.move_next();
|
||||
return Some((key, value));
|
||||
} else {
|
||||
return None;
|
||||
|
||||
@@ -109,7 +109,7 @@ use crate::{
|
||||
/// ```
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RangeBoundsSet<I, K>
|
||||
where
|
||||
I: PartialOrd,
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2022 James Forster
|
||||
|
||||
This file is part of range_bounds_map.
|
||||
|
||||
range_bounds_map is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
range_bounds_map is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
use crate::bound_ord::BoundOrd;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StartRangeBoundsOrdWrapper<I, K> {
|
||||
phantom: PhantomData<I>,
|
||||
inner: K,
|
||||
}
|
||||
|
||||
impl<I, K> Ord for StartRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
BoundOrd::start(self.inner.start_bound())
|
||||
.cmp(&BoundOrd::start(other.inner.start_bound()))
|
||||
}
|
||||
}
|
||||
impl<I, K> PartialOrd for StartRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(&other))
|
||||
}
|
||||
}
|
||||
impl<I, K> PartialEq for StartRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.cmp(&other).is_eq()
|
||||
}
|
||||
}
|
||||
impl<I, K> Eq for StartRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user