1 unstable release
| 0.4.0 | Jun 23, 2024 |
|---|---|
| 0.3.3 |
|
| 0.3.2 |
|
| 0.3.1 |
|
| 0.1.0 |
|
#897 in Algorithms
1,275 downloads per month
Used in 8 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 GenericRanges and Ranges
which will always uphold the guarantees described above e.g. for use in fuzzers.
Dependencies
~0–640KB
~12K SLoC