removed all implementation for a re-start, now compiles
This commit is contained in:
@@ -18,17 +18,27 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
use crate::bound_ord::BoundOrd;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CustomRangeBoundsOrdWrapper<K> {
|
||||
pub trait OrdBodge<K> {
|
||||
fn cmp(&self, other: &K) -> Ordering;
|
||||
}
|
||||
|
||||
pub enum CustomRangeBoundsOrdWrapper<I, K> {
|
||||
RangeBounds(K),
|
||||
OrdBodge(Box<dyn OrdBodge<K>>, PhantomData<I>),
|
||||
}
|
||||
|
||||
impl<K> CustomRangeBoundsOrdWrapper<K> {
|
||||
pub fn unwrap_range_bounds_ref(&self) -> &K {
|
||||
impl<I, K> CustomRangeBoundsOrdWrapper<I, K> {
|
||||
//todo rename these after finished
|
||||
//re-enable warnings
|
||||
//do clippy
|
||||
//check doctests
|
||||
pub fn rxr(&self) -> &K {
|
||||
match self {
|
||||
CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds) => {
|
||||
return range_bounds;
|
||||
@@ -37,7 +47,7 @@ impl<K> CustomRangeBoundsOrdWrapper<K> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_range_bounds(self) -> K {
|
||||
pub fn rx(self) -> K {
|
||||
match self {
|
||||
CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds) => {
|
||||
return range_bounds;
|
||||
@@ -47,60 +57,17 @@ impl<K> CustomRangeBoundsOrdWrapper<K> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> Ord for CustomRangeBoundsOrdWrapper<K>
|
||||
impl<I, K> Ord for CustomRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match (self, other) {
|
||||
(
|
||||
CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds),
|
||||
CustomRangeBoundsOrdWrapper::BoundOrd(bound_ord),
|
||||
) => cmp_range_bounds_with_bound_ord(
|
||||
range_bounds,
|
||||
bound_ord.as_ref(),
|
||||
),
|
||||
(
|
||||
CustomRangeBoundsOrdWrapper::BoundOrd(bound_ord),
|
||||
CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds),
|
||||
) => cmp_range_bounds_with_bound_ord(
|
||||
range_bounds,
|
||||
bound_ord.as_ref(),
|
||||
)
|
||||
.reverse(),
|
||||
_ => {
|
||||
panic!(
|
||||
"Must have ONE of each real RangeBounds and non-real BoundOrd!"
|
||||
);
|
||||
}
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn cmp_range_bounds_with_bound_ord<I, K>(
|
||||
range_bounds: &K,
|
||||
bound_ord: BoundOrd<&I>,
|
||||
) -> Ordering
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
//optimisation remove cloning here and all trait bounds that are
|
||||
//reliant on this
|
||||
let start_bound_ord = BoundOrd::start(range_bounds.start_bound());
|
||||
let end_bound_ord = BoundOrd::end(range_bounds.end_bound());
|
||||
|
||||
if bound_ord < start_bound_ord {
|
||||
Ordering::Greater
|
||||
} else if bound_ord > end_bound_ord {
|
||||
Ordering::Less
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> PartialOrd for CustomRangeBoundsOrdWrapper<K>
|
||||
impl<I, K> PartialOrd for CustomRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
@@ -110,14 +77,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> Eq for CustomRangeBoundsOrdWrapper<K>
|
||||
impl<I, K> Eq for CustomRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<I, K> PartialEq for CustomRangeBoundsOrdWrapper<K>
|
||||
impl<I, K> PartialEq for CustomRangeBoundsOrdWrapper<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
K: RangeBounds<I>,
|
||||
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
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::ops::{RangeBounds, Bound};
|
||||
|
||||
use labels::{trivial, tested};
|
||||
|
||||
use crate::bound_ord::BoundOrd;
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Config {
|
||||
LeftFirstNonOverlapping,
|
||||
LeftFirstPartialOverlap,
|
||||
LeftContainsRight,
|
||||
|
||||
RightFirstNonOverlapping,
|
||||
RightFirstPartialOverlap,
|
||||
RightContainsLeft,
|
||||
}
|
||||
|
||||
#[tested]
|
||||
fn config<I, A, B>(a: &A, b: &B) -> Config
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
B: RangeBounds<I>,
|
||||
I: Ord,
|
||||
{
|
||||
let (a_start, a_end) = expand(a);
|
||||
let (b_start, b_end) = expand(b);
|
||||
|
||||
match BoundOrd::start(a_start) < BoundOrd::start(b_start) {
|
||||
true => {
|
||||
match (
|
||||
contains_bound_ord(a, BoundOrd::start(b_start)),
|
||||
contains_bound_ord(a, BoundOrd::end(b_end)),
|
||||
) {
|
||||
(false, false) => Config::LeftFirstNonOverlapping,
|
||||
(true, false) => Config::LeftFirstPartialOverlap,
|
||||
(true, true) => Config::LeftContainsRight,
|
||||
(false, true) => unreachable!(),
|
||||
}
|
||||
}
|
||||
false => {
|
||||
match (
|
||||
contains_bound_ord(b, BoundOrd::start(a_start)),
|
||||
contains_bound_ord(b, BoundOrd::end(a_end)),
|
||||
) {
|
||||
(false, false) => Config::RightFirstNonOverlapping,
|
||||
(true, false) => Config::RightFirstPartialOverlap,
|
||||
(true, true) => Config::RightContainsLeft,
|
||||
(false, true) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum SortedConfig<I> {
|
||||
NonOverlapping((Bound<I>, Bound<I>), (Bound<I>, Bound<I>)),
|
||||
PartialOverlap((Bound<I>, Bound<I>), (Bound<I>, Bound<I>)),
|
||||
Swallowed((Bound<I>, Bound<I>), (Bound<I>, Bound<I>)),
|
||||
}
|
||||
|
||||
#[rustfmt::skip]//{{{//{{{//{{{//{{{
|
||||
#[trivial]//}}}//}}}//}}}//}}}
|
||||
fn sorted_config<'a, I, A, B>(a: &'a A, b: &'a B) -> SortedConfig<&'a I>
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
B: RangeBounds<I>,
|
||||
I: Ord,
|
||||
{
|
||||
let ae = expand(a);
|
||||
let be = expand(b);
|
||||
match config(a, b) {
|
||||
Config::LeftFirstNonOverlapping => SortedConfig::NonOverlapping(ae, be),
|
||||
Config::LeftFirstPartialOverlap => SortedConfig::Swallowed(ae, be),
|
||||
Config::LeftContainsRight => SortedConfig::Swallowed(ae, be),
|
||||
|
||||
Config::RightFirstNonOverlapping => SortedConfig::NonOverlapping(be, ae),
|
||||
Config::RightFirstPartialOverlap => SortedConfig::PartialOverlap(be, ae),
|
||||
Config::RightContainsLeft => SortedConfig::Swallowed(be, ae),
|
||||
}
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
fn contains_bound_ord<I, A>(range_bounds: &A, bound_ord: BoundOrd<&I>) -> bool
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
I: Ord,
|
||||
{
|
||||
let start_bound_ord = BoundOrd::start(range_bounds.start_bound());
|
||||
let end_bound_ord = BoundOrd::end(range_bounds.end_bound());
|
||||
|
||||
return bound_ord >= start_bound_ord && bound_ord <= end_bound_ord;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct CutResult<I> {
|
||||
before_cut: Option<(Bound<I>, Bound<I>)>,
|
||||
inside_cut: Option<(Bound<I>, Bound<I>)>,
|
||||
after_cut: Option<(Bound<I>, Bound<I>)>,
|
||||
}
|
||||
|
||||
#[tested]
|
||||
fn cut_range_bounds<'a, I, B, C>(
|
||||
base_range_bounds: &'a B,
|
||||
cut_range_bounds: &'a C,
|
||||
) -> CutResult<&'a I>
|
||||
where
|
||||
B: RangeBounds<I>,
|
||||
C: RangeBounds<I>,
|
||||
I: Ord + Clone,
|
||||
{
|
||||
let base_all @ (base_start, base_end) = (
|
||||
base_range_bounds.start_bound(),
|
||||
base_range_bounds.end_bound(),
|
||||
);
|
||||
let cut_all @ (cut_start, cut_end) =
|
||||
(cut_range_bounds.start_bound(), cut_range_bounds.end_bound());
|
||||
|
||||
let mut result = CutResult {
|
||||
before_cut: None,
|
||||
inside_cut: None,
|
||||
after_cut: None,
|
||||
};
|
||||
|
||||
match config(base_range_bounds, cut_range_bounds) {
|
||||
Config::LeftFirstNonOverlapping => {
|
||||
result.before_cut = Some(base_all);
|
||||
}
|
||||
Config::LeftFirstPartialOverlap => {
|
||||
result.before_cut = Some((base_start, flip_bound(cut_start)));
|
||||
result.inside_cut = Some((cut_start, base_end));
|
||||
}
|
||||
Config::LeftContainsRight => {
|
||||
result.before_cut = Some((base_start, flip_bound(cut_start)));
|
||||
result.inside_cut = Some(cut_all);
|
||||
// exception for Unbounded-ending things
|
||||
match cut_end {
|
||||
Bound::Unbounded => {}
|
||||
_ => {
|
||||
result.after_cut = Some((flip_bound(cut_end), base_end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Config::RightFirstNonOverlapping => {
|
||||
result.after_cut = Some(base_all);
|
||||
}
|
||||
Config::RightFirstPartialOverlap => {
|
||||
result.after_cut = Some((flip_bound(cut_end), base_end));
|
||||
result.inside_cut = Some((base_start, cut_end));
|
||||
}
|
||||
Config::RightContainsLeft => {
|
||||
result.inside_cut = Some(base_all);
|
||||
}
|
||||
}
|
||||
|
||||
//only return valid range_bounds
|
||||
return CutResult {
|
||||
before_cut: result
|
||||
.before_cut
|
||||
.filter(|x| is_valid_range_bounds::<(Bound<&I>, Bound<&I>), I>(x)),
|
||||
inside_cut: result
|
||||
.inside_cut
|
||||
.filter(|x| is_valid_range_bounds::<(Bound<&I>, Bound<&I>), I>(x)),
|
||||
after_cut: result
|
||||
.after_cut
|
||||
.filter(|x| is_valid_range_bounds::<(Bound<&I>, Bound<&I>), I>(x)),
|
||||
};
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
pub fn is_valid_range_bounds<Q, I>(range_bounds: &Q) -> bool
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
I: std::cmp::PartialOrd,
|
||||
{
|
||||
match (range_bounds.start_bound(), range_bounds.end_bound()) {
|
||||
(Bound::Included(start), Bound::Included(end)) => start <= end,
|
||||
(Bound::Included(start), Bound::Excluded(end)) => start < end,
|
||||
(Bound::Excluded(start), Bound::Included(end)) => start < end,
|
||||
(Bound::Excluded(start), Bound::Excluded(end)) => start < end,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[tested]
|
||||
fn overlaps<I, A, B>(a: &A, b: &B) -> bool
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
B: RangeBounds<I>,
|
||||
I: Ord,
|
||||
{
|
||||
!matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _))
|
||||
}
|
||||
|
||||
#[tested]
|
||||
fn touches<I, A, B>(a: &A, b: &B) -> bool
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
B: RangeBounds<I>,
|
||||
I: Ord,
|
||||
{
|
||||
match sorted_config(a, b) {
|
||||
SortedConfig::NonOverlapping(a, b) => match (a.1, b.0) {
|
||||
(Bound::Included(point1), Bound::Excluded(point2)) => {
|
||||
point1 == point2
|
||||
}
|
||||
(Bound::Excluded(point1), Bound::Included(point2)) => {
|
||||
point1 == point2
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
fn expand<I, A>(range_bounds: &A) -> (Bound<&I>, Bound<&I>)
|
||||
where
|
||||
A: RangeBounds<I>,
|
||||
{
|
||||
(range_bounds.start_bound(), range_bounds.end_bound())
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
fn flip_bound<I>(bound: Bound<&I>) -> Bound<&I> {
|
||||
match bound {
|
||||
Bound::Included(point) => Bound::Excluded(point),
|
||||
Bound::Excluded(point) => Bound::Included(point),
|
||||
Bound::Unbounded => Bound::Unbounded,
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -225,15 +225,19 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![feature(btree_cursors)]
|
||||
#![allow(clippy::tabs_in_doc_comments)]
|
||||
#![allow(clippy::needless_return)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_variables)]
|
||||
pub(crate) mod bound_ord;
|
||||
pub(crate) mod custom_range_bounds_ord_wrapper;
|
||||
pub(crate) mod helpers;
|
||||
|
||||
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;
|
||||
|
||||
+114
-1952
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user