1 unstable release
0.4.0 | Jun 23, 2024 |
---|---|
0.3.3 |
|
0.3.2 |
|
0.3.1 |
|
0.1.0 |
|
#132 in Algorithms
3,663 downloads per month
Used in 6 crates
(3 directly)
350KB
7.5K
SLoC
Ranges
Ranges
is a generic replacement for the core/std range types.
Overview
GenericRange
This is the main replacement for core/std ranges with provided From
implementations.
The only difference is, that T
needs to implement Domain
and consequently Ord
.
The start
needs to be less or equal to end
to uphold certain guarantees and allow for more optimization.
Ranges
This is a vector-backed range/interval set storing generic ranges in a ordered and always disjoint fashion.
Domain
This is the helper trait that defines the properties of a type and the domain it is in.
It is already implemented for all primitive integers, char
and bool
. Additionally there are implementations
using feature gates for noisy_float
and num-bigint
.
The default implementation of this trait is written in a way, that continuous
types need no further code (except, if applicable, their min- and maximum).
Discrete-only methods panic by default and are never called by the
library if the DISCRETE
constant is false
(which it is by default).
Examples
More examples can be found in the documentation.
GenericRange
- from core/std ranges:
use ranges::GenericRange; let generic = GenericRange::from(1..5); assert_eq!(generic.start_bound(), Bound::Included(&1)); assert_eq!(generic.end_bound(), Bound::Excluded(&5));
- overlapping union:
use ranges::{GenericRange, OperationResult}; let range = GenericRange::from(0..10); let range2 = 5..=15; assert_eq!(range | range2, OperationResult::Single((0..=15).into()));
Ranges
- find contained intersecting ranges:
use ranges::Ranges; let ranges = Ranges::from(vec![0..5, 10..20, 25..30, 45..50]); assert_eq!(ranges.find_intersecting_ranges(&(7..47).into()), Some((1, 3)));
- contains an item:
use ranges::Ranges; let ranges = Ranges::from(vec![0..3, 5..10]); assert!(ranges.contains(&2)); assert!(ranges.contains(&7)); assert!(!ranges.contains(&4));
Domain
Example implementation for a Domain
allowing only values between 0 and 100:
use ranges::Domain;
struct LimitedInt(u8);
impl LimitedInt {
const MIN: u8 = 0;
const MAX: u8 = 100;
}
impl Domain for LimitedInt {
fn predecessor(&self) -> Option<Self> {
match self {
Self::MIN => None,
_ => Some(self - 1),
}
}
fn successor(&self) -> Option<Self> {
match self {
Self::MAX => None,
_ => Some(self + 1),
}
}
fn minimum() -> Bound<Self> {
Bound::Included(Self::MIN)
}
fn maximum() -> Bound<Self> {
Bound::Included(Self::MAX)
}
}
#[test]
fn clamp_to_domain() {
let range = GenericRange::<LimitedInt>::from(0..200);
assert!(range, (0..=100).into());
}
Notes
The feature arbitrary
allows creating arbitrary GenericRange
s and Range
s
which will always uphold the guarantees described above e.g. for use in fuzzers.
Dependencies
~0–740KB
~14K SLoC