made InclusiveInterval validity a construction time invariant
This commit is contained in:
@@ -127,6 +127,10 @@ differ depending on whether the underlying type is `Discrete` or
|
|||||||
`Discrete` but `5.0..=6.0` does **not** touch `7.0..=8.0` since the
|
`Discrete` but `5.0..=6.0` does **not** touch `7.0..=8.0` since the
|
||||||
value `6.5` exists.
|
value `6.5` exists.
|
||||||
|
|
||||||
|
Importantly, this also makes Inclusive/Exclusive ended ranges really
|
||||||
|
easy to work with as they can be losslessly converted between one
|
||||||
|
another. For example, `3..6` is equivalent to `3..=5`.
|
||||||
|
|
||||||
### Finite-ness
|
### Finite-ness
|
||||||
|
|
||||||
At the moment this crate is also designed to work only with [`Finite`]
|
At the moment this crate is also designed to work only with [`Finite`]
|
||||||
|
|||||||
+12
-12
@@ -17,7 +17,7 @@ You should have received a copy of the GNU Affero General Public License
|
|||||||
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! The module containing [`DiscreteRangeMap`] and related types.
|
//! A module containing [`DiscreteRangeMap`] and related types.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
@@ -35,7 +35,7 @@ use serde::de::{SeqAccess, Visitor};
|
|||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeSeq;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
use crate::utils::{cmp_point_with_range, cut_range, is_valid_range, overlaps};
|
use crate::utils::{cmp_point_with_range, cut_range, overlaps};
|
||||||
use crate::{DiscreteFinite, InclusiveInterval};
|
use crate::{DiscreteFinite, InclusiveInterval};
|
||||||
|
|
||||||
/// An ordered map of non-overlapping ranges based on [`BTreeMap`].
|
/// An ordered map of non-overlapping ranges based on [`BTreeMap`].
|
||||||
@@ -671,7 +671,7 @@ where
|
|||||||
end: second.0.down().unwrap(),
|
end: second.0.down().unwrap(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.filter(|range| is_valid_range(*range));
|
.filter(|range| range.is_valid());
|
||||||
|
|
||||||
//possibly add the trimmed start and end gaps
|
//possibly add the trimmed start and end gaps
|
||||||
return trimmed_start_gap
|
return trimmed_start_gap
|
||||||
@@ -1261,7 +1261,7 @@ where
|
|||||||
///
|
///
|
||||||
/// let map: DiscreteRangeMap<_, _, _> =
|
/// let map: DiscreteRangeMap<_, _, _> =
|
||||||
/// DiscreteRangeMap::from_iter_strict(
|
/// DiscreteRangeMap::from_iter_strict(
|
||||||
/// slice.into_iter().filter(|(range, _)| range.start > 2),
|
/// slice.into_iter().filter(|(range, _)| range.start() > 2),
|
||||||
/// )
|
/// )
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
@@ -1428,12 +1428,12 @@ impl<I, K, V> DiscreteRangeMap<I, K, V> {
|
|||||||
|
|
||||||
// Helper Functions ==========================
|
// Helper Functions ==========================
|
||||||
|
|
||||||
fn invalid_range_panic<Q, I>(range: Q)
|
pub(crate) fn invalid_range_panic<Q, I>(range: Q)
|
||||||
where
|
where
|
||||||
I: PointType,
|
I: PointType,
|
||||||
Q: RangeType<I>,
|
Q: RangeType<I>,
|
||||||
{
|
{
|
||||||
if !is_valid_range(range) {
|
if !range.is_valid() {
|
||||||
panic!(
|
panic!(
|
||||||
"invalid range given to function see here for more details: https://docs.rs/discrete_range_map/latest/discrete_range_map/#invalid-ranges"
|
"invalid range given to function see here for more details: https://docs.rs/discrete_range_map/latest/discrete_range_map/#invalid-ranges"
|
||||||
);
|
);
|
||||||
@@ -2304,24 +2304,24 @@ mod tests {
|
|||||||
fn cut_range_bounds_should_return_valid_ranges() {
|
fn cut_range_bounds_should_return_valid_ranges() {
|
||||||
let result: CutResult<i8> = cut_range(ie(3, 8), ie(5, 8));
|
let result: CutResult<i8> = cut_range(ie(3, 8), ie(5, 8));
|
||||||
if let Some(x) = result.before_cut {
|
if let Some(x) = result.before_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
if let Some(x) = result.inside_cut {
|
if let Some(x) = result.inside_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
if let Some(x) = result.after_cut {
|
if let Some(x) = result.after_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = cut_range(ie(3, 8), ie(3, 5));
|
let result = cut_range(ie(3, 8), ie(3, 5));
|
||||||
if let Some(x) = result.before_cut {
|
if let Some(x) = result.before_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
if let Some(x) = result.inside_cut {
|
if let Some(x) = result.inside_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
if let Some(x) = result.after_cut {
|
if let Some(x) = result.after_cut {
|
||||||
assert!(is_valid_range(x));
|
assert!(x.is_valid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ You should have received a copy of the GNU Affero General Public License
|
|||||||
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! The module containing [`DiscreteRangeSet`] and related types. Since
|
//! A module containing [`DiscreteRangeSet`] and related types.
|
||||||
//! [`DiscreteRangeSet`] is just a wrapper around [`DiscreteRangeMap`], most of
|
//!
|
||||||
//! the methods' docs will point towards the equivalent method's docs on
|
//! Since [`DiscreteRangeSet`] is just a wrapper around
|
||||||
//! [`DiscreteRangeMap`] to prevent inconsistency.
|
//! [`DiscreteRangeMap`], most of the methods' docs will point towards the
|
||||||
|
//! equivalent method's docs on [`DiscreteRangeMap`] to prevent
|
||||||
|
//! inconsistency.
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|||||||
+305
-50
@@ -17,24 +17,80 @@ You should have received a copy of the GNU Affero General Public License
|
|||||||
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! A module containing [`InclusiveInterval`] and it's various constructor functions.
|
//! A module containing [`InclusiveInterval`] and its constructors.
|
||||||
|
//!
|
||||||
|
//! The constructors are not associated functions as then you must write
|
||||||
|
//! `InclusiveInterval` before it every time you want create an interval
|
||||||
|
//! which is a bit annoying as you can't import associated function in rust
|
||||||
|
//! yet. If you would still like the associated versions I would be happy to
|
||||||
|
//! add them as well, just open a PR/Issue.
|
||||||
|
|
||||||
use core::ops::{RangeBounds, Bound};
|
use core::ops::{Bound, RangeBounds};
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{DiscreteFinite, PointType, InclusiveRange};
|
use crate::discrete_range_map::invalid_range_panic;
|
||||||
|
use crate::{InclusiveRange, PointType};
|
||||||
|
|
||||||
/// The interval type used throughout this crate both for the examples and
|
/// An inclusive interval, only valid intervals can be constructed.
|
||||||
/// for use by library users if they don't wish to create their own
|
///
|
||||||
/// interval types.
|
/// This interval struct is used throughout this crate for the examples and
|
||||||
|
/// tests but can also be used by library users if they don't wish to create
|
||||||
|
/// their own interval types.
|
||||||
|
///
|
||||||
|
/// To create an `InclusiveInterval` use one of the various contrutor
|
||||||
|
/// functions which will all panic if you try to create an invalid range.
|
||||||
|
/// See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::{ee, ii};
|
||||||
|
///
|
||||||
|
/// let inclusive_interval = ii(4, 4);
|
||||||
|
/// let exclusive_interval = ee(3, 5);
|
||||||
|
///
|
||||||
|
/// assert_eq!(inclusive_interval, exclusive_interval);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```should_panic
|
||||||
|
/// use discrete_range_map::inclusive_interval::ee;
|
||||||
|
///
|
||||||
|
/// let invalid_interval = ee(4, 4);
|
||||||
|
/// ```
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub struct InclusiveInterval<I> {
|
pub struct InclusiveInterval<I> {
|
||||||
/// The start of the interval, inclusive.
|
/// The start of the interval, inclusive.
|
||||||
pub start: I,
|
pub(crate) start: I,
|
||||||
/// The end of the interval, inclusive.
|
/// The end of the interval, inclusive.
|
||||||
pub end: I,
|
pub(crate) end: I,
|
||||||
}
|
}
|
||||||
|
impl<I> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
/// The start of the range, inclusive.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ii;
|
||||||
|
///
|
||||||
|
/// assert_eq!(ii(2, 4).start(), 2);
|
||||||
|
/// ```
|
||||||
|
pub fn start(&self) -> I {
|
||||||
|
self.start
|
||||||
|
}
|
||||||
|
/// The end of the range, inclusive.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ii;
|
||||||
|
///
|
||||||
|
/// assert_eq!(ii(2, 4).end(), 4);
|
||||||
|
/// ```
|
||||||
|
pub fn end(&self) -> I {
|
||||||
|
self.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<I> RangeBounds<I> for InclusiveInterval<I>
|
impl<I> RangeBounds<I> for InclusiveInterval<I>
|
||||||
where
|
where
|
||||||
I: PointType,
|
I: PointType,
|
||||||
@@ -60,63 +116,262 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unbounded-unbounded interval
|
/// Create an new Unbounded-Unbounded interval.
|
||||||
pub fn uu() -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
start: i8::MIN,
|
///
|
||||||
end: i8::MAX,
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
}
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::uu;
|
||||||
|
/// use discrete_range_map::InclusiveInterval;
|
||||||
|
///
|
||||||
|
/// let interval1: InclusiveInterval<u8> = uu();
|
||||||
|
/// let interval2: InclusiveInterval<u8> = uu();
|
||||||
|
///
|
||||||
|
/// assert_eq!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn uu<I>() -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
|
start: I::MIN,
|
||||||
|
end: I::MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An unbounded-included interval
|
/// Create an new Unbounded-Included interval.
|
||||||
pub fn ui(x: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
start: i8::MIN,
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ui;
|
||||||
|
///
|
||||||
|
/// let interval1 = ui(1);
|
||||||
|
/// let interval2 = ui(4);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ui<I>(x: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
|
start: I::MIN,
|
||||||
end: x,
|
end: x,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An unbounded-excluded interval
|
/// Create an new Unbounded-Excluded interval.
|
||||||
pub fn ue(x: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
start: i8::MIN,
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ue;
|
||||||
|
///
|
||||||
|
/// let interval1 = ue(1);
|
||||||
|
/// let interval2 = ue(4);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ue<I>(x: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
|
start: I::MIN,
|
||||||
end: x.down().unwrap(),
|
end: x.down().unwrap(),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An included-unbounded interval
|
/// Create an new Included-Unbounded interval.
|
||||||
pub fn iu(x: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::iu;
|
||||||
|
///
|
||||||
|
/// let interval1 = iu(1);
|
||||||
|
/// let interval2 = iu(4);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn iu<I>(x: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
start: x,
|
start: x,
|
||||||
end: i8::MAX,
|
end: I::MAX,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An excluded-unbounded interval
|
/// Create an new Excluded-Unbounded interval.
|
||||||
pub fn eu(x: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::eu;
|
||||||
|
///
|
||||||
|
/// let interval1 = eu(1);
|
||||||
|
/// let interval2 = eu(4);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn eu<I>(x: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
start: x.up().unwrap(),
|
start: x.up().unwrap(),
|
||||||
end: i8::MAX,
|
end: I::MAX,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An included-included interval
|
/// Create an new Included-Included interval.
|
||||||
pub fn ii(x1: i8, x2: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval { start: x1, end: x2 }
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ii;
|
||||||
|
///
|
||||||
|
/// let interval1 = ii(0, 4);
|
||||||
|
/// let interval2 = ii(2, 6);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ii<I>(x1: I, x2: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval { start: x1, end: x2 };
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An included-excluded interval
|
/// Create an new Included-Excluded interval.
|
||||||
pub fn ie(x1: i8, x2: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ie;
|
||||||
|
///
|
||||||
|
/// let interval1 = ie(0, 4);
|
||||||
|
/// let interval2 = ie(2, 6);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ie<I>(x1: I, x2: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
start: x1,
|
start: x1,
|
||||||
end: x2.down().unwrap(),
|
end: x2.down().unwrap(),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An excluded-included interval
|
/// Create an new Excluded-Included interval.
|
||||||
pub fn ei(x1: i8, x2: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ei;
|
||||||
|
///
|
||||||
|
/// let interval1 = ei(0, 4);
|
||||||
|
/// let interval2 = ei(2, 6);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ei<I>(x1: I, x2: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
start: x1.up().unwrap(),
|
start: x1.up().unwrap(),
|
||||||
end: x2,
|
end: x2,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
/// An excluded-excluded interval
|
/// Create an new Excluded-Excluded interval.
|
||||||
pub fn ee(x1: i8, x2: i8) -> InclusiveInterval<i8> {
|
///
|
||||||
InclusiveInterval {
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is an invalid range. See [`Invalid
|
||||||
|
/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges)
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use discrete_range_map::inclusive_interval::ee;
|
||||||
|
///
|
||||||
|
/// let interval1 = ee(0, 4);
|
||||||
|
/// let interval2 = ee(2, 6);
|
||||||
|
///
|
||||||
|
/// assert_ne!(interval1, interval2)
|
||||||
|
/// ```
|
||||||
|
pub fn ee<I>(x1: I, x2: I) -> InclusiveInterval<I>
|
||||||
|
where
|
||||||
|
I: PointType,
|
||||||
|
{
|
||||||
|
let interval = InclusiveInterval {
|
||||||
start: x1.up().unwrap(),
|
start: x1.up().unwrap(),
|
||||||
end: x2.down().unwrap(),
|
end: x2.down().unwrap(),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
invalid_range_panic(interval);
|
||||||
|
|
||||||
|
interval
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -86,12 +86,12 @@ along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
//! // Second, we need to implement From<InclusiveInterval<i8>>
|
//! // Second, we need to implement From<InclusiveInterval<i8>>
|
||||||
//! impl From<InclusiveInterval<i8>> for Reservation {
|
//! impl From<InclusiveInterval<i8>> for Reservation {
|
||||||
//! fn from(value: InclusiveInterval<i8>) -> Self {
|
//! fn from(value: InclusiveInterval<i8>) -> Self {
|
||||||
//! if value.end == i8::MAX {
|
//! if value.end() == i8::MAX {
|
||||||
//! Reservation::Infinite(value.start)
|
//! Reservation::Infinite(value.start())
|
||||||
//! } else {
|
//! } else {
|
||||||
//! Reservation::Finite(
|
//! Reservation::Finite(
|
||||||
//! value.start,
|
//! value.start(),
|
||||||
//! value.end.up().unwrap(),
|
//! value.end().up().unwrap(),
|
||||||
//! )
|
//! )
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
@@ -135,6 +135,10 @@ along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
//! `Discrete` but `5.0..=6.0` does **not** touch `7.0..=8.0` since the
|
//! `Discrete` but `5.0..=6.0` does **not** touch `7.0..=8.0` since the
|
||||||
//! value `6.5` exists.
|
//! value `6.5` exists.
|
||||||
//!
|
//!
|
||||||
|
//! Importantly, this also makes Inclusive/Exclusive ended ranges really
|
||||||
|
//! easy to work with as they can be losslessly converted between one
|
||||||
|
//! another. For example, `3..6` is equivalent to `3..=5`.
|
||||||
|
//!
|
||||||
//! ### Finite-ness
|
//! ### Finite-ness
|
||||||
//!
|
//!
|
||||||
//! At the moment this crate is also designed to work only with [`Finite`]
|
//! At the moment this crate is also designed to work only with [`Finite`]
|
||||||
@@ -231,6 +235,7 @@ along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
//! // Infinity is encountered such as when it might be
|
//! // Infinity is encountered such as when it might be
|
||||||
//! // returned by `get_entry_at_point()`, for example:
|
//! // returned by `get_entry_at_point()`, for example:
|
||||||
//!
|
//!
|
||||||
|
//! use discrete_range_map::inclusive_interval::uu;
|
||||||
//! use discrete_range_map::{DiscreteRangeMap, InclusiveInterval};
|
//! use discrete_range_map::{DiscreteRangeMap, InclusiveInterval};
|
||||||
//!
|
//!
|
||||||
//! let map: DiscreteRangeMap<
|
//! let map: DiscreteRangeMap<
|
||||||
@@ -241,13 +246,7 @@ along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
//!
|
//!
|
||||||
//! let mut gap = map.get_entry_at_point(WithInfinity::Finite(4));
|
//! let mut gap = map.get_entry_at_point(WithInfinity::Finite(4));
|
||||||
//!
|
//!
|
||||||
//! assert_eq!(
|
//! assert_eq!(gap, Err(uu()));
|
||||||
//! gap,
|
|
||||||
//! Err(InclusiveInterval {
|
|
||||||
//! start: WithInfinity::Finite(0),
|
|
||||||
//! end: WithInfinity::Infinity,
|
|
||||||
//! })
|
|
||||||
//! );
|
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Invalid Ranges
|
//! ### Invalid Ranges
|
||||||
@@ -392,4 +391,3 @@ pub use crate::discrete_range_map::{
|
|||||||
};
|
};
|
||||||
pub use crate::discrete_range_set::DiscreteRangeSet;
|
pub use crate::discrete_range_set::DiscreteRangeSet;
|
||||||
pub use crate::inclusive_interval::InclusiveInterval;
|
pub use crate::inclusive_interval::InclusiveInterval;
|
||||||
|
|
||||||
|
|||||||
+4
-12
@@ -19,7 +19,7 @@ along with discrete_range_map. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{InclusiveInterval, PointType, RangeType};
|
use crate::{InclusiveInterval, PointType, RangeType, InclusiveRange};
|
||||||
|
|
||||||
pub(crate) fn cmp_point_with_range<I, K>(point: I, range: K) -> Ordering
|
pub(crate) fn cmp_point_with_range<I, K>(point: I, range: K) -> Ordering
|
||||||
where
|
where
|
||||||
@@ -190,20 +190,12 @@ where
|
|||||||
|
|
||||||
//only return valid ranges
|
//only return valid ranges
|
||||||
return CutResult {
|
return CutResult {
|
||||||
before_cut: result.before_cut.filter(|x| is_valid_range(*x)),
|
before_cut: result.before_cut.filter(|x| x.is_valid()),
|
||||||
inside_cut: result.inside_cut.filter(|x| is_valid_range(*x)),
|
inside_cut: result.inside_cut.filter(|x| x.is_valid()),
|
||||||
after_cut: result.after_cut.filter(|x| is_valid_range(*x)),
|
after_cut: result.after_cut.filter(|x| x.is_valid()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_valid_range<I, K>(range: K) -> bool
|
|
||||||
where
|
|
||||||
I: PointType,
|
|
||||||
K: RangeType<I>,
|
|
||||||
{
|
|
||||||
range.start() <= range.end()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn overlaps<I, A, B>(a: A, b: B) -> bool
|
pub(crate) fn overlaps<I, A, B>(a: A, b: B) -> bool
|
||||||
where
|
where
|
||||||
I: PointType,
|
I: PointType,
|
||||||
|
|||||||
Reference in New Issue
Block a user