checkpoint
This commit is contained in:
parent
945196d5ab
commit
b15b0fc928
@ -19,16 +19,16 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use crate::range_bounds_map::DiscreteRange;
|
||||
use crate::range_bounds_map::FiniteRange;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DiscreteBounds<I> {
|
||||
pub struct FiniteBounds<I> {
|
||||
//both are always included
|
||||
pub start: I,
|
||||
pub end: I,
|
||||
}
|
||||
|
||||
impl<I> RangeBounds<I> for DiscreteBounds<I> {
|
||||
impl<I> RangeBounds<I> for FiniteBounds<I> {
|
||||
fn start_bound(&self) -> Bound<&I> {
|
||||
Bound::Included(&self.start)
|
||||
}
|
||||
@ -37,7 +37,7 @@ impl<I> RangeBounds<I> for DiscreteBounds<I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> DiscreteRange<I> for DiscreteBounds<I> {
|
||||
impl<I> FiniteRange<I> for FiniteBounds<I> {
|
||||
fn start(&self) -> I {
|
||||
self.start
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ 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::iter::Step;
|
||||
|
||||
pub trait Discrete {
|
||||
pub trait DiscreteFinite {
|
||||
const MIN: Self;
|
||||
const MAX: Self;
|
||||
|
||||
@ -31,14 +29,10 @@ pub trait Discrete {
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl<T> Discrete for T
|
||||
where
|
||||
T: Sized + Step,
|
||||
{
|
||||
fn up(self) -> Option<Self> {
|
||||
<T as Step>::forward_checked(self, 1)
|
||||
}
|
||||
fn down(self) -> Option<Self> {
|
||||
<T as Step>::backward_checked(self, 1)
|
||||
}
|
||||
macro_rules! discrete_finite_impl_macro {
|
||||
($structname: ident, Default, $($t:tt)*) => {
|
||||
fn default() -> Self {
|
||||
Self {$($t)*}
|
||||
}
|
||||
};
|
||||
}
|
@ -221,11 +221,11 @@ pub mod test_ranges;
|
||||
pub(crate) mod utils;
|
||||
|
||||
pub mod discrete_bounds;
|
||||
pub mod stepable;
|
||||
pub mod discrete_finite;
|
||||
|
||||
pub mod range_bounds_map;
|
||||
pub mod range_bounds_set;
|
||||
|
||||
pub use crate::discrete_bounds::DiscreteBounds;
|
||||
pub use crate::discrete_bounds::FiniteBounds;
|
||||
pub use crate::range_bounds_map::{OverlapError, RangeBoundsMap};
|
||||
pub use crate::range_bounds_set::RangeBoundsSet;
|
||||
|
@ -29,8 +29,8 @@ use serde::de::{MapAccess, Visitor};
|
||||
use serde::ser::SerializeMap;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::discrete_bounds::DiscreteBounds;
|
||||
use crate::stepable::Discrete;
|
||||
use crate::discrete_bounds::FiniteBounds;
|
||||
use crate::discrete_finite::DiscreteFinite;
|
||||
use crate::utils::{cmp_point_with_range, cut_range, is_valid_range, overlaps};
|
||||
|
||||
/// An ordered map of non-overlapping ranges based on [`BTreeMap`].
|
||||
@ -139,8 +139,8 @@ pub struct OverlapError;
|
||||
|
||||
impl<I, K, V> RangeBoundsMap<I, K, V>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy,
|
||||
{
|
||||
/// Makes a new, empty `RangeBoundsMap`.
|
||||
///
|
||||
@ -222,7 +222,7 @@ where
|
||||
/// ```
|
||||
pub fn overlaps<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -259,7 +259,7 @@ where
|
||||
/// ```
|
||||
pub fn overlapping<Q>(&self, range: Q) -> impl DoubleEndedIterator<Item = (&K, &V)>
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -304,7 +304,7 @@ where
|
||||
/// ```
|
||||
pub fn overlapping_mut<Q>(&mut self, range: Q) -> impl DoubleEndedIterator<Item = (&K, &mut V)>
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -416,12 +416,12 @@ where
|
||||
/// Err(iu(100))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_entry_at_point(&self, point: I) -> Result<(&K, &V), DiscreteBounds<I>> {
|
||||
pub fn get_entry_at_point(&self, point: I) -> Result<(&K, &V), FiniteBounds<I>> {
|
||||
self.inner
|
||||
.get_key_value(overlapping_comp(point))
|
||||
.ok_or_else(|| self.get_gap_at_raw(point))
|
||||
}
|
||||
fn get_gap_at_raw(&self, point: I) -> DiscreteBounds<I> {
|
||||
fn get_gap_at_raw(&self, point: I) -> FiniteBounds<I> {
|
||||
let lower = self
|
||||
.inner
|
||||
.upper_bound(overlapping_comp(point), SearchBoundCustom::Included);
|
||||
@ -429,7 +429,7 @@ where
|
||||
.inner
|
||||
.lower_bound(overlapping_comp(point), SearchBoundCustom::Included);
|
||||
|
||||
DiscreteBounds {
|
||||
FiniteBounds {
|
||||
start: lower
|
||||
.key()
|
||||
.map_or(I::MIN, |lower| lower.end().up().unwrap()),
|
||||
@ -527,7 +527,7 @@ where
|
||||
/// ```
|
||||
pub fn remove_overlapping<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = (K, V)> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -587,10 +587,10 @@ where
|
||||
/// );
|
||||
/// assert_eq!(base, after_cut);
|
||||
/// ```
|
||||
pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = (DiscreteBounds<I>, V)> + '_
|
||||
pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = (FiniteBounds<I>, V)> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
K: From<DiscreteBounds<I>>,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
K: From<FiniteBounds<I>>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
@ -619,10 +619,10 @@ where
|
||||
&mut self,
|
||||
range: Q,
|
||||
single_overlapping_range: K,
|
||||
) -> impl Iterator<Item = (DiscreteBounds<I>, V)>
|
||||
) -> impl Iterator<Item = (FiniteBounds<I>, V)>
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
K: From<DiscreteBounds<I>>,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
K: From<FiniteBounds<I>>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
@ -653,10 +653,10 @@ where
|
||||
range: Q,
|
||||
left_overlapping: Option<K>,
|
||||
right_overlapping: Option<K>,
|
||||
) -> impl Iterator<Item = (DiscreteBounds<I>, V)> + '_
|
||||
) -> impl Iterator<Item = (FiniteBounds<I>, V)> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
K: From<DiscreteBounds<I>>,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
K: From<FiniteBounds<I>>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
@ -712,7 +712,7 @@ where
|
||||
.into_iter()
|
||||
.chain(self.remove_overlapping(range).map(|(key, value)| {
|
||||
(
|
||||
(DiscreteBounds {
|
||||
(FiniteBounds {
|
||||
start: key.start(),
|
||||
end: key.end(),
|
||||
}),
|
||||
@ -757,9 +757,9 @@ where
|
||||
/// ]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn gaps<Q>(&self, outer_range: Q) -> impl DoubleEndedIterator<Item = DiscreteBounds<I>>
|
||||
pub fn gaps<Q>(&self, outer_range: Q) -> impl DoubleEndedIterator<Item = FiniteBounds<I>>
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
invalid_range_panic(outer_range);
|
||||
|
||||
@ -811,7 +811,7 @@ where
|
||||
//find one at the time of writing
|
||||
.collect::<Vec<_>>()
|
||||
.windows(2)
|
||||
.map(|windows| DiscreteBounds {
|
||||
.map(|windows| FiniteBounds {
|
||||
start: windows[0].1.up().unwrap(),
|
||||
end: windows[1].0.down().unwrap(),
|
||||
})
|
||||
@ -854,7 +854,7 @@ where
|
||||
/// ```
|
||||
pub fn contains_range<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -910,7 +910,7 @@ where
|
||||
remove_end: R2,
|
||||
) -> K
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
G1: FnOnce(&Self, &V) -> Option<K>,
|
||||
G2: FnOnce(&Self, &V) -> Option<K>,
|
||||
R1: FnOnce(&mut Self, &V),
|
||||
@ -922,15 +922,15 @@ where
|
||||
let matching_end = get_end(self, &value);
|
||||
|
||||
let returning = match (matching_start, matching_end) {
|
||||
(Some(matching_start), Some(matching_end)) => K::from(DiscreteBounds {
|
||||
(Some(matching_start), Some(matching_end)) => K::from(FiniteBounds {
|
||||
start: matching_start.start(),
|
||||
end: matching_end.end(),
|
||||
}),
|
||||
(Some(matching_start), None) => K::from(DiscreteBounds {
|
||||
(Some(matching_start), None) => K::from(FiniteBounds {
|
||||
start: matching_start.start(),
|
||||
end: range.end(),
|
||||
}),
|
||||
(None, Some(matching_end)) => K::from(DiscreteBounds {
|
||||
(None, Some(matching_end)) => K::from(FiniteBounds {
|
||||
start: range.start(),
|
||||
end: matching_end.end(),
|
||||
}),
|
||||
@ -1009,7 +1009,7 @@ where
|
||||
/// ```
|
||||
pub fn insert_merge_touching(&mut self, range: K, value: V) -> Result<K, OverlapError>
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -1107,7 +1107,7 @@ where
|
||||
value: V,
|
||||
) -> Result<K, OverlapError>
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
V: Eq,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
@ -1208,7 +1208,7 @@ where
|
||||
/// ```
|
||||
pub fn insert_merge_overlapping(&mut self, range: K, value: V) -> K
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -1291,7 +1291,7 @@ where
|
||||
/// ```
|
||||
pub fn insert_merge_touching_or_overlapping(&mut self, range: K, value: V) -> K
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
|
||||
@ -1364,7 +1364,7 @@ where
|
||||
/// ```
|
||||
pub fn insert_overwrite(&mut self, range: K, value: V)
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
V: Clone,
|
||||
{
|
||||
invalid_range_panic(range);
|
||||
@ -1455,7 +1455,7 @@ where
|
||||
|
||||
fn invalid_range_panic<Q, I>(range: Q)
|
||||
where
|
||||
Q: DiscreteRange<I>,
|
||||
Q: FiniteRange<I>,
|
||||
I: Ord,
|
||||
{
|
||||
if !is_valid_range(range) {
|
||||
@ -1467,29 +1467,29 @@ where
|
||||
|
||||
fn double_comp<K, I>() -> impl FnMut(&K, &K) -> Ordering
|
||||
where
|
||||
K: DiscreteRange<I>,
|
||||
I: Ord + Discrete,
|
||||
K: FiniteRange<I>,
|
||||
I: Ord + DiscreteFinite,
|
||||
{
|
||||
|inner_range: &K, new_range: &K| new_range.start().cmp(&inner_range.start())
|
||||
}
|
||||
fn overlapping_comp<I, K>(point: I) -> impl FnMut(&K) -> Ordering
|
||||
where
|
||||
I: Ord + Copy,
|
||||
K: DiscreteRange<I> + Copy,
|
||||
K: FiniteRange<I> + Copy,
|
||||
{
|
||||
move |inner_range: &K| cmp_point_with_range(point, *inner_range)
|
||||
}
|
||||
fn touching_start_comp<I, K>(start: I) -> impl FnMut(&K) -> Ordering
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I>,
|
||||
{
|
||||
move |inner_range: &K| start.cmp(&inner_range.end().up().unwrap())
|
||||
}
|
||||
fn touching_end_comp<I, K>(end: I) -> impl FnMut(&K) -> Ordering
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I>,
|
||||
{
|
||||
move |inner_range: &K| end.cmp(&inner_range.start().down().unwrap())
|
||||
}
|
||||
@ -1497,7 +1497,7 @@ where
|
||||
/// A simple helper trait to make my implemtation nicer, if you
|
||||
/// already implement RangeBounds and Copy on your type then this will
|
||||
/// also be implemted.
|
||||
pub trait DiscreteRange<I> {
|
||||
pub trait FiniteRange<I> {
|
||||
fn start(&self) -> I;
|
||||
fn end(&self) -> I;
|
||||
}
|
||||
@ -1544,8 +1544,8 @@ impl<I, K, V> Default for RangeBoundsMap<I, K, V> {
|
||||
|
||||
impl<I, K, V> Serialize for RangeBoundsMap<I, K, V>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Serialize,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Serialize,
|
||||
V: Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@ -1562,8 +1562,8 @@ where
|
||||
|
||||
impl<'de, I, K, V> Deserialize<'de> for RangeBoundsMap<I, K, V>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Deserialize<'de>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Deserialize<'de>,
|
||||
V: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
@ -1586,8 +1586,8 @@ struct RangeBoundsMapVisitor<I, K, V> {
|
||||
|
||||
impl<'de, I, K, V> Visitor<'de> for RangeBoundsMapVisitor<I, K, V>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Deserialize<'de>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Deserialize<'de>,
|
||||
V: Deserialize<'de>,
|
||||
{
|
||||
type Value = RangeBoundsMap<I, K, V>;
|
||||
@ -1623,7 +1623,7 @@ mod tests {
|
||||
//go a bit around on either side to compensate for Unbounded
|
||||
pub(crate) const NUMBERS_DOMAIN: &'static [i8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
||||
|
||||
fn basic() -> RangeBoundsMap<i8, DiscreteBounds<i8>, bool> {
|
||||
fn basic() -> RangeBoundsMap<i8, FiniteBounds<i8>, bool> {
|
||||
RangeBoundsMap::from_slice_strict([
|
||||
(ui(4), false),
|
||||
(ee(5, 7), true),
|
||||
@ -1632,7 +1632,7 @@ mod tests {
|
||||
])
|
||||
.unwrap()
|
||||
}
|
||||
fn basic_slice() -> [(DiscreteBounds<i8>, bool); 4] {
|
||||
fn basic_slice() -> [(FiniteBounds<i8>, bool); 4] {
|
||||
[
|
||||
(ui(4), false),
|
||||
(ee(5, 7), true),
|
||||
@ -1660,10 +1660,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_insert_strict<const N: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_insert: (DiscreteBounds<i8>, bool),
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_insert: (FiniteBounds<i8>, bool),
|
||||
result: Result<(), OverlapError>,
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
assert_eq!(before.insert_strict(to_insert.0, to_insert.1), result);
|
||||
assert_eq!(before, RangeBoundsMap::from_slice_strict(after).unwrap())
|
||||
@ -1674,7 +1674,7 @@ mod tests {
|
||||
//case zero
|
||||
for overlap_range in all_valid_test_bounds() {
|
||||
//you can't overlap nothing
|
||||
assert!(RangeBoundsMap::<i8, DiscreteBounds<i8>, ()>::new()
|
||||
assert!(RangeBoundsMap::<i8, FiniteBounds<i8>, ()>::new()
|
||||
.overlapping(overlap_range)
|
||||
.next()
|
||||
.is_none());
|
||||
@ -1769,10 +1769,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_remove_overlapping<const N: usize, const Y: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_remove: DiscreteBounds<i8>,
|
||||
result: [(DiscreteBounds<i8>, bool); N],
|
||||
after: Option<[(DiscreteBounds<i8>, bool); Y]>,
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_remove: FiniteBounds<i8>,
|
||||
result: [(FiniteBounds<i8>, bool); N],
|
||||
after: Option<[(FiniteBounds<i8>, bool); Y]>,
|
||||
) {
|
||||
let clone = before.clone();
|
||||
assert_eq!(
|
||||
@ -1825,10 +1825,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_cut<const N: usize, const Y: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_cut: DiscreteBounds<i8>,
|
||||
result: [(DiscreteBounds<i8>, bool); Y],
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_cut: FiniteBounds<i8>,
|
||||
result: [(FiniteBounds<i8>, bool); Y],
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
let clone = before.clone();
|
||||
assert_eq!(before.cut(to_cut).collect::<Vec<_>>(), result);
|
||||
@ -1862,9 +1862,9 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_gaps<const N: usize>(
|
||||
map: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
outer_range: DiscreteBounds<i8>,
|
||||
result: [DiscreteBounds<i8>; N],
|
||||
map: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
outer_range: FiniteBounds<i8>,
|
||||
result: [FiniteBounds<i8>; N],
|
||||
) {
|
||||
assert_eq!(map.gaps(outer_range).collect::<Vec<_>>(), result);
|
||||
}
|
||||
@ -1912,10 +1912,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_insert_merge_touching<const N: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_insert: (DiscreteBounds<i8>, bool),
|
||||
result: Result<DiscreteBounds<i8>, OverlapError>,
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_insert: (FiniteBounds<i8>, bool),
|
||||
result: Result<FiniteBounds<i8>, OverlapError>,
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
assert_eq!(
|
||||
before.insert_merge_touching(to_insert.0, to_insert.1),
|
||||
@ -1967,10 +1967,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_insert_merge_touching_if_values_equal<const N: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_insert: (DiscreteBounds<i8>, bool),
|
||||
result: Result<DiscreteBounds<i8>, OverlapError>,
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_insert: (FiniteBounds<i8>, bool),
|
||||
result: Result<FiniteBounds<i8>, OverlapError>,
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
assert_eq!(
|
||||
before.insert_merge_touching_if_values_equal(to_insert.0, to_insert.1),
|
||||
@ -2023,10 +2023,10 @@ mod tests {
|
||||
assert_insert_merge_overlapping(basic(), (uu(), false), uu(), [(uu(), false)]);
|
||||
}
|
||||
fn assert_insert_merge_overlapping<const N: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_insert: (DiscreteBounds<i8>, bool),
|
||||
result: DiscreteBounds<i8>,
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_insert: (FiniteBounds<i8>, bool),
|
||||
result: FiniteBounds<i8>,
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
assert_eq!(
|
||||
before.insert_merge_overlapping(to_insert.0, to_insert.1),
|
||||
@ -2094,10 +2094,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_insert_merge_touching_or_overlapping<const N: usize>(
|
||||
mut before: RangeBoundsMap<i8, DiscreteBounds<i8>, bool>,
|
||||
to_insert: (DiscreteBounds<i8>, bool),
|
||||
result: DiscreteBounds<i8>,
|
||||
after: [(DiscreteBounds<i8>, bool); N],
|
||||
mut before: RangeBoundsMap<i8, FiniteBounds<i8>, bool>,
|
||||
to_insert: (FiniteBounds<i8>, bool),
|
||||
result: FiniteBounds<i8>,
|
||||
after: [(FiniteBounds<i8>, bool); N],
|
||||
) {
|
||||
assert_eq!(
|
||||
before.insert_merge_touching_or_overlapping(to_insert.0, to_insert.1),
|
||||
@ -2187,7 +2187,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn con(x: Option<DiscreteBounds<i8>>, point: &i8) -> bool {
|
||||
fn con(x: Option<FiniteBounds<i8>>, point: &i8) -> bool {
|
||||
match x {
|
||||
Some(y) => contains_point(y, *point),
|
||||
None => false,
|
||||
@ -2220,7 +2220,7 @@ mod tests {
|
||||
|
||||
// Test Helper Functions
|
||||
//======================
|
||||
fn all_non_overlapping_test_bound_entries() -> Vec<(DiscreteBounds<i8>, DiscreteBounds<i8>)> {
|
||||
fn all_non_overlapping_test_bound_entries() -> Vec<(FiniteBounds<i8>, FiniteBounds<i8>)> {
|
||||
let mut output = Vec::new();
|
||||
for test_bounds1 in all_valid_test_bounds() {
|
||||
for test_bounds2 in all_valid_test_bounds() {
|
||||
@ -2233,12 +2233,12 @@ mod tests {
|
||||
return output;
|
||||
}
|
||||
|
||||
fn all_valid_test_bounds() -> Vec<DiscreteBounds<i8>> {
|
||||
fn all_valid_test_bounds() -> Vec<FiniteBounds<i8>> {
|
||||
let mut output = Vec::new();
|
||||
for i in NUMBERS {
|
||||
for j in NUMBERS {
|
||||
if i <= j {
|
||||
output.push(DiscreteBounds { start: *i, end: *j });
|
||||
output.push(FiniteBounds { start: *i, end: *j });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ 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::{DiscreteRange, IntoIter as RangeBoundsMapIntoIter};
|
||||
use crate::stepable::Discrete;
|
||||
use crate::discrete_bounds::FiniteBounds;
|
||||
use crate::discrete_finite::DiscreteFinite;
|
||||
use crate::range_bounds_map::{FiniteRange, IntoIter as RangeBoundsMapIntoIter};
|
||||
use crate::{OverlapError, RangeBoundsMap};
|
||||
|
||||
/// An ordered set of non-overlapping ranges based on [`RangeBoundsMap`].
|
||||
@ -30,8 +30,8 @@ pub struct RangeBoundsSet<I, K> {
|
||||
|
||||
impl<I, K> RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy,
|
||||
{
|
||||
/// See [`RangeBoundsMap::new()`] for more details.
|
||||
pub fn new() -> Self {
|
||||
@ -50,19 +50,19 @@ where
|
||||
/// See [`RangeBoundsMap::overlaps()`] for more details.
|
||||
pub fn overlaps<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
self.inner.overlaps(range)
|
||||
}
|
||||
/// See [`RangeBoundsMap::overlapping()`] for more details.
|
||||
pub fn overlapping<Q>(&self, range: Q) -> impl DoubleEndedIterator<Item = &K>
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
self.inner.overlapping(range).map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::get_entry_at_point()`] for more details.
|
||||
pub fn get_at_point(&self, point: I) -> Result<K, DiscreteBounds<I>> {
|
||||
pub fn get_at_point(&self, point: I) -> Result<K, FiniteBounds<I>> {
|
||||
self.inner.get_entry_at_point(point).map(first).copied()
|
||||
}
|
||||
/// See [`RangeBoundsMap::contains_point()`] for more details.
|
||||
@ -76,35 +76,29 @@ where
|
||||
/// See [`RangeBoundsMap::remove_overlapping()`] for more details.
|
||||
pub fn remove_overlapping<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = K> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
{
|
||||
self.inner.remove_overlapping(range).map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::cut()`] for more details.
|
||||
pub fn cut<'a, Q>(
|
||||
&'a mut self,
|
||||
range: Q,
|
||||
) -> impl Iterator<Item = DiscreteBounds<I>> + '_
|
||||
pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator<Item = FiniteBounds<I>> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
K: From<DiscreteBounds<I>>,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
self.inner.cut(range).map(first)
|
||||
}
|
||||
/// See [`RangeBoundsMap::gaps()`] for more details.
|
||||
pub fn gaps<'a, Q>(
|
||||
&'a self,
|
||||
range: Q,
|
||||
) -> impl DoubleEndedIterator<Item = DiscreteBounds<I>> + '_
|
||||
pub fn gaps<'a, Q>(&'a self, range: Q) -> impl DoubleEndedIterator<Item = FiniteBounds<I>> + '_
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy + 'a,
|
||||
Q: FiniteRange<I> + Copy + 'a,
|
||||
{
|
||||
self.inner.gaps(range)
|
||||
}
|
||||
/// See [`RangeBoundsMap::contains_range()`] for more details.
|
||||
pub fn contains_range<Q>(&self, range: Q) -> bool
|
||||
where
|
||||
Q: DiscreteRange<I> + Copy,
|
||||
Q: FiniteRange<I> + Copy,
|
||||
{
|
||||
self.inner.contains_range(range)
|
||||
}
|
||||
@ -113,36 +107,30 @@ where
|
||||
self.inner.insert_strict(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_touching()`] for more details.
|
||||
pub fn insert_merge_touching(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> Result<K, OverlapError>
|
||||
pub fn insert_merge_touching(&mut self, range: K) -> Result<K, OverlapError>
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
self.inner.insert_merge_touching(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_overlapping()`] for more details.
|
||||
pub fn insert_merge_overlapping(&mut self, range: K) -> K
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
self.inner.insert_merge_overlapping(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_merge_touching_or_overlapping()`] for more details.
|
||||
pub fn insert_merge_touching_or_overlapping(
|
||||
&mut self,
|
||||
range: K,
|
||||
) -> K
|
||||
pub fn insert_merge_touching_or_overlapping(&mut self, range: K) -> K
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
self.inner.insert_merge_touching_or_overlapping(range, ())
|
||||
}
|
||||
/// See [`RangeBoundsMap::insert_overwrite()`] for more details.
|
||||
pub fn insert_overwrite(&mut self, range: K)
|
||||
where
|
||||
K: From<DiscreteBounds<I>>,
|
||||
K: From<FiniteBounds<I>>,
|
||||
{
|
||||
self.inner.insert_overwrite(range, ())
|
||||
}
|
||||
@ -214,8 +202,8 @@ where
|
||||
|
||||
impl<I, K> Serialize for RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Serialize,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -231,8 +219,8 @@ where
|
||||
|
||||
impl<'de, I, K> Deserialize<'de> for RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Deserialize<'de>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
@ -252,8 +240,8 @@ struct RangeBoundsSetVisitor<I, K> {
|
||||
|
||||
impl<'de, I, K> Visitor<'de> for RangeBoundsSetVisitor<I, K>
|
||||
where
|
||||
I: Ord + Copy + Discrete,
|
||||
K: DiscreteRange<I> + Copy + Deserialize<'de>,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
K: FiniteRange<I> + Copy + Deserialize<'de>,
|
||||
{
|
||||
type Value = RangeBoundsSet<I, K>;
|
||||
|
||||
|
@ -1,26 +1,26 @@
|
||||
use crate::discrete_bounds::DiscreteBounds;
|
||||
use crate::stepable::Discrete;
|
||||
use crate::discrete_bounds::FiniteBounds;
|
||||
use crate::discrete_finite::DiscreteFinite;
|
||||
|
||||
pub fn uu() -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn uu() -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: i8::MIN,
|
||||
end: i8::MAX,
|
||||
}
|
||||
}
|
||||
pub fn ui(x: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn ui(x: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: i8::MIN,
|
||||
end: x,
|
||||
}
|
||||
}
|
||||
pub fn ue(x: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn ue(x: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: i8::MIN,
|
||||
end: x.down().unwrap(),
|
||||
}
|
||||
}
|
||||
pub fn iu(x: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn iu(x: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: x,
|
||||
end: i8::MAX,
|
||||
}
|
||||
@ -28,23 +28,23 @@ pub fn iu(x: i8) -> DiscreteBounds<i8> {
|
||||
//fn eu(x: i8) -> TestBounds {
|
||||
//(Bound::Excluded(x), Bound::Unbounded)
|
||||
//}
|
||||
pub fn ii(x1: i8, x2: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds { start: x1, end: x2 }
|
||||
pub fn ii(x1: i8, x2: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds { start: x1, end: x2 }
|
||||
}
|
||||
pub fn ie(x1: i8, x2: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn ie(x1: i8, x2: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: x1.up().unwrap(),
|
||||
end: x2.down().unwrap(),
|
||||
}
|
||||
}
|
||||
pub fn ei(x1: i8, x2: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn ei(x1: i8, x2: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: x1.up().unwrap(),
|
||||
end: x2,
|
||||
}
|
||||
}
|
||||
pub fn ee(x1: i8, x2: i8) -> DiscreteBounds<i8> {
|
||||
DiscreteBounds {
|
||||
pub fn ee(x1: i8, x2: i8) -> FiniteBounds<i8> {
|
||||
FiniteBounds {
|
||||
start: x1.up().unwrap(),
|
||||
end: x2.down().unwrap(),
|
||||
}
|
||||
|
80
src/utils.rs
80
src/utils.rs
@ -19,14 +19,14 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::discrete_bounds::DiscreteBounds;
|
||||
use crate::range_bounds_map::DiscreteRange;
|
||||
use crate::stepable::Discrete;
|
||||
use crate::discrete_bounds::FiniteBounds;
|
||||
use crate::discrete_finite::DiscreteFinite;
|
||||
use crate::range_bounds_map::FiniteRange;
|
||||
|
||||
pub(crate) fn cmp_point_with_range<I, K>(point: I, range: K) -> Ordering
|
||||
where
|
||||
I: Ord,
|
||||
K: DiscreteRange<I>,
|
||||
K: FiniteRange<I>,
|
||||
{
|
||||
if point < range.start() {
|
||||
Ordering::Less
|
||||
@ -49,8 +49,8 @@ pub(crate) enum Config {
|
||||
}
|
||||
pub(crate) fn config<I, A, B>(a: A, b: B) -> Config
|
||||
where
|
||||
A: DiscreteRange<I> + Copy,
|
||||
B: DiscreteRange<I> + Copy,
|
||||
A: FiniteRange<I> + Copy,
|
||||
B: FiniteRange<I> + Copy,
|
||||
I: Ord,
|
||||
{
|
||||
if a.start() < b.start() {
|
||||
@ -71,18 +71,24 @@ where
|
||||
}
|
||||
|
||||
enum SortedConfig<I> {
|
||||
NonOverlapping(DiscreteBounds<I>, DiscreteBounds<I>),
|
||||
PartialOverlap(DiscreteBounds<I>, DiscreteBounds<I>),
|
||||
Swallowed(DiscreteBounds<I>, DiscreteBounds<I>),
|
||||
NonOverlapping(FiniteBounds<I>, FiniteBounds<I>),
|
||||
PartialOverlap(FiniteBounds<I>, FiniteBounds<I>),
|
||||
Swallowed(FiniteBounds<I>, FiniteBounds<I>),
|
||||
}
|
||||
fn sorted_config<I, A, B>(a: A, b: B) -> SortedConfig<I>
|
||||
where
|
||||
A: DiscreteRange<I> + Copy,
|
||||
B: DiscreteRange<I> + Copy,
|
||||
A: FiniteRange<I> + Copy,
|
||||
B: FiniteRange<I> + Copy,
|
||||
I: Ord,
|
||||
{
|
||||
let ae = (a.start(), a.end());
|
||||
let be = (b.start(), b.end());
|
||||
let ae = FiniteBounds {
|
||||
start: a.start(),
|
||||
end: a.end(),
|
||||
};
|
||||
let be = FiniteBounds {
|
||||
start: b.start(),
|
||||
end: b.end(),
|
||||
};
|
||||
match config(a, b) {
|
||||
Config::LeftFirstNonOverlapping => SortedConfig::NonOverlapping(ae, be),
|
||||
Config::LeftFirstPartialOverlap => SortedConfig::Swallowed(ae, be),
|
||||
@ -96,7 +102,7 @@ where
|
||||
|
||||
pub(crate) fn contains_point<I, A>(range: A, point: I) -> bool
|
||||
where
|
||||
A: DiscreteRange<I>,
|
||||
A: FiniteRange<I>,
|
||||
I: Ord,
|
||||
{
|
||||
cmp_point_with_range(point, range).is_eq()
|
||||
@ -104,15 +110,15 @@ where
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct CutResult<I> {
|
||||
pub(crate) before_cut: Option<DiscreteBounds<I>>,
|
||||
pub(crate) inside_cut: Option<DiscreteBounds<I>>,
|
||||
pub(crate) after_cut: Option<DiscreteBounds<I>>,
|
||||
pub(crate) before_cut: Option<FiniteBounds<I>>,
|
||||
pub(crate) inside_cut: Option<FiniteBounds<I>>,
|
||||
pub(crate) after_cut: Option<FiniteBounds<I>>,
|
||||
}
|
||||
pub(crate) fn cut_range<I, B, C>(base: B, cut: C) -> CutResult<I>
|
||||
where
|
||||
B: DiscreteRange<I> + Copy,
|
||||
C: DiscreteRange<I> + Copy,
|
||||
I: Ord + Copy + Discrete,
|
||||
B: FiniteRange<I> + Copy,
|
||||
C: FiniteRange<I> + Copy,
|
||||
I: Ord + Copy + DiscreteFinite,
|
||||
{
|
||||
let mut result = CutResult {
|
||||
before_cut: None,
|
||||
@ -122,54 +128,54 @@ where
|
||||
|
||||
match config(base, cut) {
|
||||
Config::LeftFirstNonOverlapping => {
|
||||
result.before_cut = Some(DiscreteBounds {
|
||||
result.before_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: base.end(),
|
||||
});
|
||||
}
|
||||
Config::LeftFirstPartialOverlap => {
|
||||
result.before_cut = Some(DiscreteBounds {
|
||||
result.before_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: cut.start().down_if_finite(),
|
||||
end: cut.start().down().unwrap(),
|
||||
});
|
||||
result.inside_cut = Some(DiscreteBounds {
|
||||
result.inside_cut = Some(FiniteBounds {
|
||||
start: cut.start(),
|
||||
end: base.end(),
|
||||
});
|
||||
}
|
||||
Config::LeftContainsRight => {
|
||||
result.before_cut = Some(DiscreteBounds {
|
||||
result.before_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: cut.start().down_if_finite(),
|
||||
end: cut.start().down().unwrap(),
|
||||
});
|
||||
result.inside_cut = Some(DiscreteBounds {
|
||||
result.inside_cut = Some(FiniteBounds {
|
||||
start: cut.start(),
|
||||
end: cut.end(),
|
||||
});
|
||||
result.after_cut = Some(DiscreteBounds {
|
||||
start: cut.end().up_if_finite(),
|
||||
result.after_cut = Some(FiniteBounds {
|
||||
start: cut.end().up().unwrap(),
|
||||
end: base.end(),
|
||||
});
|
||||
}
|
||||
|
||||
Config::RightFirstNonOverlapping => {
|
||||
result.after_cut = Some(DiscreteBounds {
|
||||
result.after_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: base.end(),
|
||||
});
|
||||
}
|
||||
Config::RightFirstPartialOverlap => {
|
||||
result.after_cut = Some(DiscreteBounds {
|
||||
start: cut.end().up_if_finite(),
|
||||
result.after_cut = Some(FiniteBounds {
|
||||
start: cut.end().up().unwrap(),
|
||||
end: base.end(),
|
||||
});
|
||||
result.inside_cut = Some(DiscreteBounds {
|
||||
result.inside_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: cut.end(),
|
||||
});
|
||||
}
|
||||
Config::RightContainsLeft => {
|
||||
result.inside_cut = Some(DiscreteBounds {
|
||||
result.inside_cut = Some(FiniteBounds {
|
||||
start: base.start(),
|
||||
end: base.end(),
|
||||
});
|
||||
@ -187,15 +193,15 @@ where
|
||||
pub(crate) fn is_valid_range<I, K>(range: K) -> bool
|
||||
where
|
||||
I: Ord,
|
||||
K: DiscreteRange<I>,
|
||||
K: FiniteRange<I>,
|
||||
{
|
||||
range.start() <= range.end()
|
||||
}
|
||||
|
||||
pub(crate) fn overlaps<I, A, B>(a: A, b: B) -> bool
|
||||
where
|
||||
A: DiscreteRange<I> + Copy,
|
||||
B: DiscreteRange<I> + Copy,
|
||||
A: FiniteRange<I> + Copy,
|
||||
B: FiniteRange<I> + Copy,
|
||||
I: Ord,
|
||||
{
|
||||
!matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _))
|
||||
|
Loading…
x
Reference in New Issue
Block a user