nearly there, a few more tests!!
This commit is contained in:
parent
ac2d0a724c
commit
f0c469cd17
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -9,10 +9,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "btree_monstousity"
|
||||
version = "0.0.4"
|
||||
name = "btree_monstrousity"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a596671a3fb8cd1899005c5cdc5ce442fe4d0153abbe12917171f7d435831563"
|
||||
checksum = "e30d101bbd3dff04ef3aae2c6d01bf4d250269a477a20e3d56af229371b4e243"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rustversion",
|
||||
@ -116,7 +116,7 @@ dependencies = [
|
||||
name = "range_bounds_map"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"btree_monstousity",
|
||||
"btree_monstrousity",
|
||||
"either",
|
||||
"itertools",
|
||||
"ordered-float",
|
||||
|
@ -18,7 +18,7 @@ categories = ["data-structures"]
|
||||
[dependencies]
|
||||
serde = {version = "1.0.148", features = ["derive"]}
|
||||
itertools = "0.10.5"
|
||||
btree_monstousity = {version ="0.0.4", features = ["btree_drain_filter"]}
|
||||
btree_monstrousity = {version ="0.0.3", features = ["btree_drain_filter", "btree_cursors"]}
|
||||
either = "1.8.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -204,19 +204,19 @@ where
|
||||
!matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _))
|
||||
}
|
||||
|
||||
pub(crate) fn touches<I, A, B>(a: A, b: B) -> bool
|
||||
pub(crate) fn this_touches_that<I, A, B>(a: A, b: B) -> bool
|
||||
where
|
||||
A: NiceRange<I>,
|
||||
B: NiceRange<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
|
||||
match config(a, b) {
|
||||
Config::LeftFirstNonOverlapping => match (a.end(), b.start()) {
|
||||
(Bound::Included(end), Bound::Excluded(start)) if end == start => {
|
||||
true
|
||||
}
|
||||
(Bound::Excluded(point1), Bound::Included(point2)) => {
|
||||
point1 == point2
|
||||
(Bound::Excluded(end), Bound::Included(start)) if end == start => {
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
|
@ -23,8 +23,8 @@ use std::iter::once;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use btree_monstousity::btree_map::SearchBoundCustom;
|
||||
use btree_monstousity::BTreeMap;
|
||||
use btree_monstrousity::btree_map::SearchBoundCustom;
|
||||
use btree_monstrousity::BTreeMap;
|
||||
use either::Either;
|
||||
use itertools::Itertools;
|
||||
use serde::de::{MapAccess, Visitor};
|
||||
@ -34,6 +34,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use crate::bound_ord::BoundOrd;
|
||||
use crate::helpers::{
|
||||
cmp_range_with_bound_ord, cut_range, flip_bound, is_valid_range, overlaps,
|
||||
this_touches_that,
|
||||
};
|
||||
use crate::TryFromBounds;
|
||||
|
||||
@ -165,7 +166,8 @@ pub struct OverlapError;
|
||||
/// use range_bounds_map::{RangeBoundsMap, TryFromBoundsError};
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(2, 8), true)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(2, 8), true)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert!(map.cut(&(4..=6)).is_err());
|
||||
/// ```
|
||||
@ -459,7 +461,8 @@ where
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// if let Some(x) = map.get_at_point_mut(&2) {
|
||||
/// *x = true;
|
||||
@ -924,27 +927,23 @@ where
|
||||
self.inner.insert(range, value, double_comp());
|
||||
}
|
||||
|
||||
fn insert_merge_with_comps<G1, G2, C1, C2>(
|
||||
fn insert_merge_with_comps<G1, G2, R1, R2>(
|
||||
&mut self,
|
||||
range: K,
|
||||
value: V,
|
||||
start_comp_generator: G1,
|
||||
end_comp_generator: G2,
|
||||
get_start: G1,
|
||||
get_end: G2,
|
||||
remove_start: R1,
|
||||
remove_end: R2,
|
||||
) -> Result<K, TryFromBoundsError>
|
||||
where
|
||||
G1: Fn(Bound<I>) -> C1,
|
||||
G2: Fn(Bound<I>) -> C2,
|
||||
C1: FnMut(&K) -> Ordering,
|
||||
C2: FnMut(&K) -> Ordering,
|
||||
G1: FnOnce(&Self) -> Option<&K>,
|
||||
G2: FnOnce(&Self) -> Option<&K>,
|
||||
R1: FnOnce(&mut Self),
|
||||
R2: FnOnce(&mut Self),
|
||||
{
|
||||
let matching_start = self
|
||||
.inner
|
||||
.get_key_value(start_comp_generator(range.start()))
|
||||
.map(|(key, _)| key);
|
||||
let matching_end = self
|
||||
.inner
|
||||
.get_key_value(end_comp_generator(range.end()))
|
||||
.map(|(key, _)| key);
|
||||
let matching_start = get_start(self);
|
||||
let matching_end = get_end(self);
|
||||
|
||||
let returning = match (matching_start, matching_end) {
|
||||
(Some(matching_start), Some(matching_end)) => {
|
||||
@ -959,8 +958,10 @@ where
|
||||
(None, None) => range,
|
||||
};
|
||||
|
||||
self.inner.remove(start_comp_generator(range.start()));
|
||||
self.inner.remove(end_comp_generator(range.end()));
|
||||
remove_start(self);
|
||||
remove_end(self);
|
||||
|
||||
let _ = self.remove_overlapping(range);
|
||||
|
||||
self.insert_unchecked(returning, value);
|
||||
|
||||
@ -998,10 +999,14 @@ where
|
||||
/// };
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(map.insert_merge_touching(ie(4, 6), true), Ok(ie(1, 6)));
|
||||
/// assert_eq!(
|
||||
/// map.insert_merge_touching(ie(4, 6), true),
|
||||
/// Ok(ie(1, 6))
|
||||
/// );
|
||||
///
|
||||
/// // Overlapping
|
||||
/// assert_eq!(
|
||||
@ -1032,8 +1037,24 @@ where
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
touching_start_comp,
|
||||
touching_end_comp,
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.get_key_value(touching_start_comp(range.start()))
|
||||
.map(|(key, _)| key)
|
||||
},
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.get_key_value(touching_end_comp(range.end()))
|
||||
.map(|(key, _)| key)
|
||||
},
|
||||
|selfy| {
|
||||
selfy.inner.remove(touching_start_comp(range.start()));
|
||||
},
|
||||
|selfy| {
|
||||
selfy.inner.remove(touching_end_comp(range.end()));
|
||||
},
|
||||
)
|
||||
.map_err(OverlapOrTryFromBoundsError::TryFromBounds)
|
||||
}
|
||||
@ -1064,7 +1085,8 @@ where
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(
|
||||
@ -1097,8 +1119,24 @@ where
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
overlapping_start_comp,
|
||||
overlapping_end_comp,
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.get_key_value(overlapping_start_comp(range.start()))
|
||||
.map(|(key, _)| key)
|
||||
},
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.get_key_value(overlapping_end_comp(range.end()))
|
||||
.map(|(key, _)| key)
|
||||
},
|
||||
|selfy| {
|
||||
selfy.inner.remove(overlapping_start_comp(range.start()));
|
||||
},
|
||||
|selfy| {
|
||||
selfy.inner.remove(overlapping_end_comp(range.end()));
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -1128,7 +1166,8 @@ where
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(1, 4), false)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(
|
||||
@ -1161,8 +1200,72 @@ where
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
touching_or_overlapping_start_comp,
|
||||
touching_or_overlapping_end_comp,
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.lower_bound(
|
||||
touching_or_overlapping_start_comp(range.start()),
|
||||
SearchBoundCustom::Included,
|
||||
)
|
||||
.key_value()
|
||||
.map(|(key, _)| key)
|
||||
.filter(|selected_range| {
|
||||
cmp_range_with_bound_ord(
|
||||
**selected_range,
|
||||
BoundOrd::start(range.start()),
|
||||
)
|
||||
.is_eq() || this_touches_that(**selected_range, range)
|
||||
})
|
||||
},
|
||||
|selfy| {
|
||||
selfy
|
||||
.inner
|
||||
.upper_bound(
|
||||
touching_or_overlapping_end_comp(range.end()),
|
||||
SearchBoundCustom::Included,
|
||||
)
|
||||
.key_value()
|
||||
.map(|(key, _)| key)
|
||||
.filter(|selected_range| {
|
||||
cmp_range_with_bound_ord(
|
||||
**selected_range,
|
||||
BoundOrd::end(range.end()),
|
||||
)
|
||||
.is_eq() || this_touches_that(range, **selected_range)
|
||||
})
|
||||
},
|
||||
|selfy| {
|
||||
let mut cursor_mut = selfy.inner.lower_bound_mut(
|
||||
touching_or_overlapping_start_comp(range.start()),
|
||||
SearchBoundCustom::Included,
|
||||
);
|
||||
if let Some(selected_range) = cursor_mut.key() {
|
||||
if cmp_range_with_bound_ord(
|
||||
*selected_range,
|
||||
BoundOrd::start(range.start()),
|
||||
)
|
||||
.is_eq() || this_touches_that(*selected_range, range)
|
||||
{
|
||||
cursor_mut.remove_current();
|
||||
}
|
||||
}
|
||||
},
|
||||
|selfy| {
|
||||
let mut cursor_mut = selfy.inner.upper_bound_mut(
|
||||
touching_or_overlapping_end_comp(range.end()),
|
||||
SearchBoundCustom::Included,
|
||||
);
|
||||
if let Some(selected_range) = cursor_mut.key() {
|
||||
if cmp_range_with_bound_ord(
|
||||
*selected_range,
|
||||
BoundOrd::end(range.end()),
|
||||
)
|
||||
.is_eq() || this_touches_that(range, *selected_range)
|
||||
{
|
||||
cursor_mut.remove_current();
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -1190,7 +1293,8 @@ where
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(2, 8), false)]).unwrap();
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(2, 8), false)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(map.insert_overwrite(ie(4, 6), true), Ok(()));
|
||||
///
|
||||
@ -1266,6 +1370,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering
|
||||
where
|
||||
K: NiceRange<I>,
|
||||
I: Ord,
|
||||
{
|
||||
|inner_range: &K, new_range: &K| {
|
||||
BoundOrd::start(new_range.start())
|
||||
.cmp(&BoundOrd::start(inner_range.start()))
|
||||
}
|
||||
}
|
||||
fn overlapping_start_comp<I, K>(start: Bound<I>) -> impl FnMut(&K) -> Ordering
|
||||
where
|
||||
I: Ord + Copy,
|
||||
@ -1284,16 +1398,6 @@ where
|
||||
cmp_range_with_bound_ord(*inner_range, BoundOrd::end(end))
|
||||
}
|
||||
}
|
||||
fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering
|
||||
where
|
||||
K: NiceRange<I>,
|
||||
I: Ord,
|
||||
{
|
||||
|inner_range: &K, new_range: &K| {
|
||||
BoundOrd::start(new_range.start())
|
||||
.cmp(&BoundOrd::start(inner_range.start()))
|
||||
}
|
||||
}
|
||||
fn touching_start_comp<I, K>(start: Bound<I>) -> impl FnMut(&K) -> Ordering
|
||||
where
|
||||
I: Ord + Copy,
|
||||
@ -1315,7 +1419,7 @@ where
|
||||
//we overide any Equals to a random non-Equal since we
|
||||
//don't want non-touching matches
|
||||
match normal_result {
|
||||
Ordering::Equal => Ordering::Less,
|
||||
Ordering::Equal => Ordering::Greater,
|
||||
x => x,
|
||||
}
|
||||
}
|
||||
@ -1422,7 +1526,7 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::bound_ord::BoundOrd;
|
||||
use crate::helpers::{config, touches, Config, CutResult};
|
||||
use crate::helpers::{config, Config, CutResult};
|
||||
|
||||
type TestBounds = (Bound<u8>, Bound<u8>);
|
||||
|
||||
@ -2293,31 +2397,29 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn touches_tests() {
|
||||
for range_bounds1 in all_valid_test_bounds() {
|
||||
for range_bounds2 in all_valid_test_bounds() {
|
||||
let our_answer = touches(range_bounds1, range_bounds2);
|
||||
//todo delete me
|
||||
//#[test]
|
||||
//fn touches_tests() {
|
||||
//for range_bounds1 in all_valid_test_bounds() {
|
||||
//for range_bounds2 in all_valid_test_bounds() {
|
||||
//let our_answer = touches(range_bounds1, range_bounds2);
|
||||
|
||||
let mathematical_definition_of_touches =
|
||||
NUMBERS_DOMAIN.iter().tuple_windows().any(|(x1, x2)| {
|
||||
(range_bounds1.contains(x1)
|
||||
&& !range_bounds1.contains(x2)
|
||||
&& range_bounds2.contains(x2)
|
||||
&& !range_bounds2.contains(x1))
|
||||
|| (range_bounds1.contains(x2)
|
||||
&& !range_bounds1.contains(x1) && range_bounds2
|
||||
.contains(x1) && !range_bounds2.contains(x2))
|
||||
});
|
||||
//let mathematical_definition_of_touches =
|
||||
//NUMBERS_DOMAIN.iter().tuple_windows().any(|(x1, x2)| {
|
||||
//(range_bounds1.contains(x1)
|
||||
//&& !range_bounds1.contains(x2)
|
||||
//&& range_bounds2.contains(x2)
|
||||
//&& !range_bounds2.contains(x1))
|
||||
//|| (range_bounds1.contains(x2)
|
||||
//&& !range_bounds1.contains(x1) && range_bounds2
|
||||
//.contains(x1) && !range_bounds2.contains(x2))
|
||||
//});
|
||||
|
||||
if our_answer != mathematical_definition_of_touches {
|
||||
dbg!(range_bounds1, range_bounds2);
|
||||
dbg!(mathematical_definition_of_touches, our_answer);
|
||||
panic!("Discrepency in touches() detected!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if our_answer != mathematical_definition_of_touches {
|
||||
//dbg!(range_bounds1, range_bounds2);
|
||||
//dbg!(mathematical_definition_of_touches, our_answer);
|
||||
//panic!("Discrepency in touches() detected!");
|
||||
//}
|
||||
|
||||
// Test Helper Functions
|
||||
//======================
|
||||
|
Loading…
x
Reference in New Issue
Block a user