after a bit not sure what I changed
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
use std::ops::Bound;
|
||||
|
||||
pub trait BoundExt<T> {
|
||||
fn inner(&self) -> Option<&T>;
|
||||
fn is_unbounded(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<T> BoundExt<T> for Bound<T> {
|
||||
fn inner(&self) -> Option<&T> {
|
||||
match self {
|
||||
Bound::Included(inner) => Some(inner),
|
||||
Bound::Excluded(inner) => Some(inner),
|
||||
Bound::Unbounded => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_unbounded(&self) -> bool {
|
||||
match self {
|
||||
Bound::Unbounded => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::range_bounds::RangeBounds;
|
||||
|
||||
pub enum StartBound<T> {
|
||||
Included(T),
|
||||
Excluded(T),
|
||||
Unbounded,
|
||||
}
|
||||
|
||||
impl<T> StartBound<T> {
|
||||
pub fn inner(&self) -> Option<&T> {
|
||||
match self {
|
||||
StartBound::Included(inner) => Some(inner),
|
||||
StartBound::Excluded(inner) => Some(inner),
|
||||
StartBound::Unbounded => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unbounded(&self) -> bool {
|
||||
match self {
|
||||
StartBound::Unbounded => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_outer(&self) -> StartBound<&T> {
|
||||
match self {
|
||||
StartBound::Included(ref point) => StartBound::Included(point),
|
||||
StartBound::Excluded(ref point) => StartBound::Excluded(point),
|
||||
StartBound::Unbounded => StartBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> StartBound<&T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
pub fn cloned(&self) -> StartBound<T> {
|
||||
match self {
|
||||
StartBound::Included(point) => {
|
||||
StartBound::Included((*point).clone())
|
||||
}
|
||||
StartBound::Excluded(point) => {
|
||||
StartBound::Excluded((*point).clone())
|
||||
}
|
||||
StartBound::Unbounded => StartBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for StartBound<T>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self.inner(), other.inner()) {
|
||||
(Some(start1), Some(start2)) => start1 == start2,
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for StartBound<T> where T: PartialEq {}
|
||||
|
||||
impl<T> PartialOrd for StartBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self.inner(), other.inner()) {
|
||||
//todo fix meh
|
||||
(Some(start1), Some(start2)) => start1.partial_cmp(start2),
|
||||
(None, Some(_)) => Some(Ordering::Less),
|
||||
(Some(_), None) => Some(Ordering::Greater),
|
||||
(None, None) => Some(Ordering::Equal),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for StartBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<EndBound<T>> for StartBound<T> {
|
||||
fn from(end_bound: EndBound<T>) -> Self {
|
||||
match end_bound {
|
||||
EndBound::Included(point) => StartBound::Included(point),
|
||||
EndBound::Excluded(point) => StartBound::Excluded(point),
|
||||
EndBound::Unbounded => StartBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum EndBound<T> {
|
||||
Included(T),
|
||||
Excluded(T),
|
||||
Unbounded,
|
||||
}
|
||||
|
||||
impl<T> EndBound<T> {
|
||||
pub fn inner(&self) -> Option<&T> {
|
||||
match self {
|
||||
EndBound::Included(inner) => Some(inner),
|
||||
EndBound::Excluded(inner) => Some(inner),
|
||||
EndBound::Unbounded => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unbounded(&self) -> bool {
|
||||
match self {
|
||||
EndBound::Unbounded => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_outer(&self) -> EndBound<&T> {
|
||||
match self {
|
||||
EndBound::Included(ref point) => EndBound::Included(point),
|
||||
EndBound::Excluded(ref point) => EndBound::Excluded(point),
|
||||
EndBound::Unbounded => EndBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EndBound<&T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
pub fn cloned(&self) -> EndBound<T> {
|
||||
match self {
|
||||
EndBound::Included(point) => EndBound::Included((*point).clone()),
|
||||
EndBound::Excluded(point) => EndBound::Excluded((*point).clone()),
|
||||
EndBound::Unbounded => EndBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for EndBound<T>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self.inner(), other.inner()) {
|
||||
(Some(start1), Some(start2)) => start1 == start2,
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for EndBound<T> where T: PartialEq {}
|
||||
|
||||
impl<T> PartialOrd for EndBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self.inner(), other.inner()) {
|
||||
//todo fix meh
|
||||
(Some(start1), Some(start2)) => start1.partial_cmp(start2),
|
||||
(None, Some(_)) => Some(Ordering::Less),
|
||||
(Some(_), None) => Some(Ordering::Greater),
|
||||
(None, None) => Some(Ordering::Equal),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for EndBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<StartBound<T>> for EndBound<T> {
|
||||
fn from(start_bound: StartBound<T>) -> Self {
|
||||
match start_bound {
|
||||
StartBound::Included(point) => EndBound::Included(point),
|
||||
StartBound::Excluded(point) => EndBound::Excluded(point),
|
||||
StartBound::Unbounded => EndBound::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RangeBounds<EndBound<T>>
|
||||
for (StartBound<EndBound<T>>, EndBound<EndBound<T>>)
|
||||
where
|
||||
T: Ord,
|
||||
{
|
||||
fn start_bound(&self) -> StartBound<&EndBound<T>> {
|
||||
self.0.copy_outer()
|
||||
}
|
||||
fn end_bound(&self) -> EndBound<&EndBound<T>> {
|
||||
self.1.copy_outer()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#![feature(is_some_and)]
|
||||
pub mod bound_ext;
|
||||
pub mod range_bounds_ext;
|
||||
pub mod bounds;
|
||||
pub mod range_bounds;
|
||||
pub mod range_bounds_set;
|
||||
pub mod specific_bounds;
|
||||
|
||||
pub use std::ops::RangeBounds as StdRangeBounds;
|
||||
pub use std::ops::Bound as StdBound;
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
use crate::bounds::{EndBound, StartBound};
|
||||
|
||||
use crate::bound_ext::BoundExt;
|
||||
|
||||
pub trait RangeBoundsExt<T> {
|
||||
fn overlaps(&self, other: &Self) -> bool;
|
||||
fn get_pair(&self) -> (Bound<&T>, Bound<&T>);
|
||||
}
|
||||
|
||||
impl<T, K> RangeBoundsExt<T> for K
|
||||
pub trait RangeBounds<T>
|
||||
where
|
||||
K: RangeBounds<T>,
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn get_pair(&self) -> (Bound<&T>, Bound<&T>) {
|
||||
fn start_bound(&self) -> StartBound<&T>;
|
||||
fn end_bound(&self) -> EndBound<&T>;
|
||||
fn get_pair(&self) -> (StartBound<&T>, EndBound<&T>) {
|
||||
(self.start_bound(), self.end_bound())
|
||||
}
|
||||
fn contains(&self, item: &T) -> bool {
|
||||
(match self.start_bound() {
|
||||
StartBound::Included(start) => start <= item,
|
||||
StartBound::Excluded(start) => start < item,
|
||||
StartBound::Unbounded => true,
|
||||
}) && (match self.end_bound() {
|
||||
EndBound::Included(end) => item <= end,
|
||||
EndBound::Excluded(end) => item < end,
|
||||
EndBound::Unbounded => true,
|
||||
})
|
||||
}
|
||||
fn overlaps(&self, other: &Self) -> bool {
|
||||
let self_start_contained = self
|
||||
.start_bound()
|
||||
@@ -38,8 +43,8 @@ where
|
||||
&& other.end_bound().is_unbounded();
|
||||
let same_exclusive = match (self.get_pair(), other.get_pair()) {
|
||||
(
|
||||
(Bound::Excluded(start1), Bound::Excluded(end1)),
|
||||
(Bound::Excluded(start2), Bound::Excluded(end2)),
|
||||
(StartBound::Excluded(start1), EndBound::Excluded(end1)),
|
||||
(StartBound::Excluded(start2), EndBound::Excluded(end2)),
|
||||
) if start1 == start2 && end1 == end2 => true,
|
||||
_ => false,
|
||||
};
|
||||
@@ -1,23 +1,19 @@
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::collections::{BTreeSet, HashMap, BTreeMap};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use derive_new::new;
|
||||
|
||||
use crate::specific_bounds::{EndBound, StartBound};
|
||||
use crate::bounds::{EndBound, StartBound};
|
||||
use crate::range_bounds::RangeBounds;
|
||||
use crate::StdBound;
|
||||
|
||||
type Id = u128;
|
||||
|
||||
//todo switch to slot map thingy
|
||||
#[derive(Default, new)]
|
||||
#[derive(new)]
|
||||
pub struct RangeBoundsSet<T, I> {
|
||||
#[new(default)]
|
||||
ranges: HashMap<Id, T>,
|
||||
#[new(default)]
|
||||
starts: BTreeSet<StartBound<I>>,
|
||||
#[new(default)]
|
||||
ends: BTreeSet<EndBound<I>>,
|
||||
phantom_data: PhantomData<I>,
|
||||
#[new(value="BTreeMap::new()")]
|
||||
starts: BTreeMap<StartBound<I>, T>,
|
||||
|
||||
#[new(default)]
|
||||
id: u128,
|
||||
@@ -30,18 +26,24 @@ where
|
||||
{
|
||||
//returns Err(()) if the inserting the given range overlaps another range
|
||||
//coalesces ranges if they touch
|
||||
pub fn insert(&mut self, range: T) -> Result<(), ()> {
|
||||
pub fn insert(&mut self, range_bounds: T) -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn raw_insert(&mut self, range: T) {}
|
||||
pub fn raw_insert(&mut self, range_bounds: T) {}
|
||||
|
||||
pub fn overlapping(&self, range: T) {
|
||||
let end_bounds_range = (
|
||||
EndBound::from(range.start_bound().cloned()),
|
||||
EndBound::from(range.end_bound().cloned()),
|
||||
pub fn overlapping(&self, range_bounds: T) {
|
||||
let start_range_bounds = (
|
||||
//we require the EndBound:Ord imlementation to work with
|
||||
//the Included range only
|
||||
StdBound::Included(range_bounds.start_bound().cloned()),
|
||||
StdBound::Included(StartBound::from(range_bounds.end_bound().cloned())),
|
||||
);
|
||||
self.ends.range(end_bounds_range);
|
||||
//this range will hold all the ranges we want except possibly
|
||||
//the last RangeBounds
|
||||
let ends_range = self.starts.range(start_range_bounds);
|
||||
|
||||
let possible_missing_range_bounds = self.starts.
|
||||
}
|
||||
|
||||
pub fn get(&self, point: &I) {}
|
||||
@@ -70,17 +72,17 @@ mod tests {
|
||||
// script to streamline the manual input process. The script
|
||||
// essentially enumerates all of the generated cases and asks me
|
||||
// to input the expected
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Rusts Bounds types are overly ambiguous in RangeBouns, it
|
||||
// should return StartBound and EndBound so that you can
|
||||
// implement Ord on them
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Rusts Bounds types are overly ambiguous in RangeBouns, it
|
||||
// should return StartBound and EndBound so that you can
|
||||
// implement Ord on them
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use crate::bound_ext::BoundExt;
|
||||
|
||||
pub enum EndBound<T> {
|
||||
Included(T),
|
||||
Excluded(T),
|
||||
Unbounded,
|
||||
}
|
||||
|
||||
impl<T> PartialEq for EndBound<T>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self.inner(), other.inner()) {
|
||||
(Some(start1), Some(start2)) => start1 == start2,
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for EndBound<T> where T: PartialEq {}
|
||||
|
||||
impl<T> PartialOrd for EndBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self.inner(), other.inner()) {
|
||||
//todo fix meh
|
||||
(Some(start1), Some(start2)) => start1.partial_cmp(start2),
|
||||
(None, Some(_)) => Some(Ordering::Less),
|
||||
(Some(_), None) => Some(Ordering::Greater),
|
||||
(None, None) => Some(Ordering::Equal),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for EndBound<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RangeBounds<EndBound<T>> for (EndBound<T>, EndBound<T>) {
|
||||
fn start_bound(&self) -> Bound<&EndBound<T>> {
|
||||
self.0
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&EndBound<T>> {
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> BoundExt<T> for EndBound<T> {
|
||||
fn inner(&self) -> Option<&T> {
|
||||
match self {
|
||||
EndBound::Included(inner) => Some(inner),
|
||||
EndBound::Excluded(inner) => Some(inner),
|
||||
EndBound::Unbounded => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_unbounded(&self) -> bool {
|
||||
match self {
|
||||
EndBound::Unbounded => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Bound<T>> for EndBound<T> {
|
||||
fn from(value: Bound<T>) -> Self {
|
||||
match value {
|
||||
Bound::Included(item) => EndBound::Included(item),
|
||||
Bound::Excluded(item) => EndBound::Excluded(item),
|
||||
Bound::Unbounded => Self::Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user