#![cfg_attr(feature = "from_slice", feature(portable_simd))]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
mod dyn_sorted_disjoint;
mod from_slice;
mod integer;
mod merge;
mod not_iter;
pub mod prelude;
mod ranges;
#[cfg(feature = "rog-experimental")]
mod rog;
mod sorted_disjoint;
mod tests;
mod union_iter;
mod unsorted_disjoint;
pub use crate::ranges::{IntoRangesIter, RangesIter};
use alloc::{collections::BTreeMap, vec::Vec};
use core::{
cmp::{max, Ordering},
convert::From,
fmt,
iter::FusedIterator,
ops::{BitOr, BitOrAssign, Bound, RangeBounds, RangeInclusive},
str::FromStr,
};
pub use dyn_sorted_disjoint::DynSortedDisjoint;
use gen_ops::gen_ops_ex;
use itertools::Tee;
pub use merge::{KMerge, Merge};
pub use not_iter::NotIter;
use num_traits::{ops::overflowing::OverflowingSub, CheckedAdd, One, WrappingSub, Zero};
#[cfg(feature = "rog-experimental")]
pub use rog::{Rog, RogsIter};
pub use sorted_disjoint::{CheckSortedDisjoint, SortedDisjoint, SortedStarts};
pub use union_iter::UnionIter;
pub use unsorted_disjoint::AssumeSortedStarts;
use unsorted_disjoint::SortedDisjointWithLenSoFar;
use unsorted_disjoint::UnsortedDisjoint;
pub trait Integer:
num_integer::Integer
+ FromStr
+ Copy
+ fmt::Display
+ fmt::Debug
+ core::iter::Sum
+ num_traits::NumAssignOps
+ num_traits::Bounded
+ num_traits::NumCast
+ Send
+ Sync
+ OverflowingSub
+ CheckedAdd
+ WrappingSub
{
#[cfg(feature = "from_slice")]
fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self>;
type SafeLen: core::hash::Hash
+ num_integer::Integer
+ num_traits::NumAssignOps
+ num_traits::Bounded
+ num_traits::NumCast
+ num_traits::One
+ core::ops::AddAssign
+ core::ops::SubAssign
+ Copy
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Send
+ Default
+ fmt::Debug
+ fmt::Display;
fn safe_len(range: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen;
fn safe_max_value() -> Self {
Self::max_value()
}
fn f64_to_safe_len(f: f64) -> Self::SafeLen;
fn safe_len_to_f64(len: Self::SafeLen) -> f64;
fn add_len_less_one(a: Self, b: Self::SafeLen) -> Self;
fn sub_len_less_one(a: Self, b: Self::SafeLen) -> Self;
}
#[derive(Clone, Hash, Default, PartialEq)]
pub struct RangeSetBlaze<T: Integer> {
len: <T as Integer>::SafeLen,
btree_map: BTreeMap<T, T>,
}
impl<T: Integer> fmt::Debug for RangeSetBlaze<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ranges().to_string())
}
}
impl<T: Integer> fmt::Display for RangeSetBlaze<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ranges().to_string())
}
}
impl<T: Integer> RangeSetBlaze<T> {
pub fn iter(&self) -> Iter<T, RangesIter<T>> {
Iter {
option_range_front: None,
option_range_back: None,
iter: self.ranges(),
}
}
#[must_use]
pub fn first(&self) -> Option<T> {
self.btree_map.iter().next().map(|(x, _)| *x)
}
pub fn get(&self, value: T) -> Option<T> {
if self.contains(value) {
Some(value)
} else {
None
}
}
#[must_use]
pub fn last(&self) -> Option<T> {
self.btree_map.iter().next_back().map(|(_, x)| *x)
}
pub fn from_sorted_disjoint<I>(iter: I) -> Self
where
I: SortedDisjoint<T>,
{
let mut iter_with_len = SortedDisjointWithLenSoFar::from(iter);
let btree_map = BTreeMap::from_iter(&mut iter_with_len);
Self {
btree_map,
len: iter_with_len.len_so_far(),
}
}
pub fn from_sorted_starts<I>(iter: I) -> Self
where
I: SortedStarts<T>,
{
Self::from_sorted_disjoint(UnionIter::new(iter))
}
#[cfg(feature = "from_slice")]
#[inline]
pub fn from_slice(slice: impl AsRef<[T]>) -> Self {
T::from_slice(slice)
}
fn _len_slow(&self) -> <T as Integer>::SafeLen {
Self::btree_map_len(&self.btree_map)
}
pub fn append(&mut self, other: &mut Self) {
for range in other.ranges() {
self.internal_add(range);
}
other.clear();
}
pub fn clear(&mut self) {
self.btree_map.clear();
self.len = <T as Integer>::SafeLen::zero();
}
#[must_use]
#[inline]
pub fn is_empty(&self) -> bool {
self.ranges_len() == 0
}
#[must_use]
#[inline]
pub fn is_subset(&self, other: &RangeSetBlaze<T>) -> bool {
if self.len() > other.len() {
return false;
}
self.ranges().is_subset(other.ranges())
}
#[must_use]
pub fn is_superset(&self, other: &Self) -> bool {
other.is_subset(self)
}
pub fn contains(&self, value: T) -> bool {
assert!(
value <= T::safe_max_value(),
"value must be <= T::safe_max_value()"
);
self.btree_map
.range(..=value)
.next_back()
.map_or(false, |(_, end)| value <= *end)
}
#[must_use]
#[inline]
pub fn is_disjoint(&self, other: &Self) -> bool {
self.ranges().is_disjoint(other.ranges())
}
fn delete_extra(&mut self, internal_range: &RangeInclusive<T>) {
let (start, end) = internal_range.clone().into_inner();
let mut after = self.btree_map.range_mut(start..);
let (start_after, end_after) = after.next().unwrap(); debug_assert!(start == *start_after && end == *end_after);
let mut end_new = end;
let delete_list = after
.map_while(|(start_delete, end_delete)| {
if *start_delete <= end || *start_delete <= end + T::one() {
end_new = max(end_new, *end_delete);
self.len -= T::safe_len(&(*start_delete..=*end_delete));
Some(*start_delete)
} else {
None
}
})
.collect::<Vec<_>>();
if end_new > end {
self.len += T::safe_len(&(end..=end_new - T::one()));
*end_after = end_new;
}
for start in delete_list {
self.btree_map.remove(&start);
}
}
pub fn insert(&mut self, value: T) -> bool {
let len_before = self.len;
self.internal_add(value..=value);
self.len != len_before
}
pub fn range<R>(&self, range: R) -> IntoIter<T>
where
R: RangeBounds<T>,
{
let start = match range.start_bound() {
Bound::Included(n) => *n,
Bound::Excluded(n) => *n + T::one(),
Bound::Unbounded => T::min_value(),
};
let end = match range.end_bound() {
Bound::Included(n) => *n,
Bound::Excluded(n) => *n - T::one(),
Bound::Unbounded => T::safe_max_value(),
};
assert!(start <= end);
let bounds = CheckSortedDisjoint::from([start..=end]);
Self::from_sorted_disjoint(self.ranges() & bounds).into_iter()
}
pub fn ranges_insert(&mut self, range: RangeInclusive<T>) -> bool {
let len_before = self.len;
self.internal_add(range);
self.len != len_before
}
pub fn remove(&mut self, value: T) -> bool {
assert!(
value <= T::safe_max_value(),
"value must be <= T::safe_max_value()"
);
let Some((start_ref, end_ref)) = self.btree_map.range_mut(..=value).next_back() else {
return false;
};
let end = *end_ref;
if end < value {
return false;
}
let start = *start_ref;
if start < value {
*end_ref = value - T::one();
if value == end {
self.len -= <T::SafeLen>::one();
return true;
}
}
self.len -= <T::SafeLen>::one();
if start == value {
self.btree_map.remove(&start);
};
if value < end {
self.btree_map.insert(value + T::one(), end);
}
true
}
pub fn split_off(&mut self, value: T) -> Self {
assert!(
value <= T::safe_max_value(),
"value must be <= T::safe_max_value()"
);
let old_len = self.len;
let mut b = self.btree_map.split_off(&value);
if let Some(mut last_entry) = self.btree_map.last_entry() {
let end_ref = last_entry.get_mut();
if value <= *end_ref {
b.insert(value, *end_ref);
*end_ref = value - T::one();
}
}
let b_len = if self.btree_map.len() < b.len() {
self.len = Self::btree_map_len(&self.btree_map);
old_len - self.len
} else {
let b_len = Self::btree_map_len(&b);
self.len = old_len - b_len;
b_len
};
Self {
btree_map: b,
len: b_len,
}
}
fn btree_map_len(btree_map: &BTreeMap<T, T>) -> T::SafeLen {
btree_map
.iter()
.fold(<T as Integer>::SafeLen::zero(), |acc, (start, end)| {
acc + T::safe_len(&(*start..=*end))
})
}
pub fn take(&mut self, value: T) -> Option<T> {
if self.remove(value) {
Some(value)
} else {
None
}
}
pub fn replace(&mut self, value: T) -> Option<T> {
if self.insert(value) {
None
} else {
Some(value)
}
}
fn internal_add(&mut self, range: RangeInclusive<T>) {
let (start, end) = range.clone().into_inner();
assert!(
end <= T::safe_max_value(),
"end must be <= T::safe_max_value()"
);
if end < start {
return;
}
let mut before = self.btree_map.range_mut(..=start).rev();
if let Some((start_before, end_before)) = before.next() {
if match (*end_before).checked_add(&T::one()) {
Some(end_before_succ) => end_before_succ < start,
None => false,
} {
self.internal_add2(&range);
} else if *end_before < end {
self.len += T::safe_len(&(*end_before..=end - T::one()));
*end_before = end;
let start_before = *start_before;
self.delete_extra(&(start_before..=end));
} else {
}
} else {
self.internal_add2(&range);
}
}
fn internal_add2(&mut self, internal_range: &RangeInclusive<T>) {
let (start, end) = internal_range.clone().into_inner();
let was_there = self.btree_map.insert(start, end);
debug_assert!(was_there.is_none()); self.delete_extra(internal_range);
self.len += T::safe_len(internal_range);
}
#[must_use]
pub const fn len(&self) -> <T as Integer>::SafeLen {
self.len
}
#[must_use]
pub fn new() -> Self {
Self {
btree_map: BTreeMap::new(),
len: <T as Integer>::SafeLen::zero(),
}
}
pub fn pop_first(&mut self) -> Option<T> {
if let Some(entry) = self.btree_map.first_entry() {
let (start, end) = entry.remove_entry();
self.len -= T::safe_len(&(start..=end));
if start != end {
let start = start + T::one();
self.btree_map.insert(start, end);
self.len += T::safe_len(&(start..=end));
}
Some(start)
} else {
None
}
}
pub fn pop_last(&mut self) -> Option<T> {
let Some(mut entry) = self.btree_map.last_entry() else {
return None;
};
let start = *entry.key();
let end = entry.get_mut();
let result = *end;
self.len -= T::safe_len(&(start..=*end));
if start == *end {
entry.remove_entry();
} else {
*end -= T::one();
self.len += T::safe_len(&(start..=*end));
}
Some(result)
}
pub fn ranges(&self) -> RangesIter<'_, T> {
RangesIter {
iter: self.btree_map.iter(),
}
}
pub fn into_ranges(self) -> IntoRangesIter<T> {
IntoRangesIter {
iter: self.btree_map.into_iter(),
}
}
#[must_use]
pub fn ranges_len(&self) -> usize {
self.btree_map.len()
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
*self = self.iter().filter(|v| f(v)).collect();
}
}
impl<T: Integer> FromIterator<T> for RangeSetBlaze<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
iter.into_iter().map(|x| x..=x).collect()
}
}
impl<'a, T: Integer> FromIterator<&'a T> for RangeSetBlaze<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = &'a T>,
{
iter.into_iter().map(|x| *x..=*x).collect()
}
}
impl<T: Integer> FromIterator<RangeInclusive<T>> for RangeSetBlaze<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = RangeInclusive<T>>,
{
let union_iter: UnionIter<T, _> = iter.into_iter().collect();
Self::from_sorted_disjoint(union_iter)
}
}
impl<'a, T: Integer + 'a> FromIterator<&'a RangeInclusive<T>> for RangeSetBlaze<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = &'a RangeInclusive<T>>,
{
let union_iter: UnionIter<T, _> = iter.into_iter().cloned().collect();
Self::from_sorted_disjoint(union_iter)
}
}
impl<T: Integer, const N: usize> From<[T; N]> for RangeSetBlaze<T> {
#[cfg(not(feature = "from_slice"))]
fn from(arr: [T; N]) -> Self {
arr.into_iter().collect()
}
#[cfg(feature = "from_slice")]
fn from(arr: [T; N]) -> Self {
Self::from_slice(arr)
}
}
#[doc(hidden)]
pub type BitOrMerge<T, L, R> = UnionIter<T, Merge<T, L, R>>;
#[doc(hidden)]
pub type BitOrKMerge<T, I> = UnionIter<T, KMerge<T, I>>;
#[doc(hidden)]
pub type BitAndMerge<T, L, R> = NotIter<T, BitNandMerge<T, L, R>>;
#[doc(hidden)]
pub type BitAndKMerge<T, I> = NotIter<T, BitNandKMerge<T, I>>;
#[doc(hidden)]
pub type BitNandMerge<T, L, R> = BitOrMerge<T, NotIter<T, L>, NotIter<T, R>>;
#[doc(hidden)]
pub type BitNandKMerge<T, I> = BitOrKMerge<T, NotIter<T, I>>;
#[doc(hidden)]
pub type BitNorMerge<T, L, R> = NotIter<T, BitOrMerge<T, L, R>>;
#[doc(hidden)]
pub type BitSubMerge<T, L, R> = NotIter<T, BitOrMerge<T, NotIter<T, L>, R>>;
#[doc(hidden)]
pub type BitXOrTee<T, L, R> =
BitOrMerge<T, BitSubMerge<T, Tee<L>, Tee<R>>, BitSubMerge<T, Tee<R>, Tee<L>>>;
#[doc(hidden)]
pub type BitXOr<T, L, R> = BitOrMerge<T, BitSubMerge<T, L, Tee<R>>, BitSubMerge<T, Tee<R>, L>>;
#[doc(hidden)]
pub type BitEq<T, L, R> = BitOrMerge<
T,
NotIter<T, BitOrMerge<T, NotIter<T, Tee<L>>, NotIter<T, Tee<R>>>>,
NotIter<T, BitOrMerge<T, Tee<L>, Tee<R>>>,
>;
impl<T, I> MultiwayRangeSetBlazeRef<T> for I
where
T: Integer,
I: IntoIterator<Item = RangeSetBlaze<T>>,
{
}
pub trait MultiwayRangeSetBlazeRef<T: Integer>:
IntoIterator<Item = RangeSetBlaze<T>> + Sized
{
fn union(self) -> RangeSetBlaze<T> {
RangeSetBlaze::from_sorted_disjoint(self.into_iter().map(|x| x.into_ranges()).union())
}
fn intersection(self) -> RangeSetBlaze<T> {
self.into_iter()
.map(RangeSetBlaze::into_ranges)
.intersection()
.into_range_set_blaze()
}
}
impl<'a, T, I> MultiwayRangeSetBlaze<'a, T> for I
where
T: Integer + 'a,
I: IntoIterator<Item = &'a RangeSetBlaze<T>>,
{
}
pub trait MultiwayRangeSetBlaze<'a, T: Integer + 'a>:
IntoIterator<Item = &'a RangeSetBlaze<T>> + Sized
{
fn union(self) -> RangeSetBlaze<T> {
self.into_iter()
.map(RangeSetBlaze::ranges)
.union()
.into_range_set_blaze()
}
fn intersection(self) -> RangeSetBlaze<T> {
self.into_iter()
.map(RangeSetBlaze::ranges)
.intersection()
.into_range_set_blaze()
}
}
impl<T, II, I> MultiwaySortedDisjoint<T, I> for II
where
T: Integer,
I: SortedDisjoint<T>,
II: IntoIterator<Item = I>,
{
}
pub trait MultiwaySortedDisjoint<T: Integer, I>: IntoIterator<Item = I> + Sized
where
I: SortedDisjoint<T>,
{
fn union(self) -> BitOrKMerge<T, I> {
UnionIter::new(KMerge::new(self))
}
fn intersection(self) -> BitAndKMerge<T, I> {
self.into_iter()
.map(|seq| seq.into_iter().complement())
.union()
.complement()
}
}
gen_ops_ex!(
<T>;
types ref RangeSetBlaze<T>, ref RangeSetBlaze<T> => RangeSetBlaze<T>;
for & call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
(a.ranges() & b.ranges()).into_range_set_blaze()
};
for ^ call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
let lhs0 = a.ranges();
let lhs1 = a.ranges();
let rhs0 = b.ranges();
let rhs1 = b.ranges();
((lhs0 - rhs0) | (rhs1 - lhs1)).into_range_set_blaze()
};
for - call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
(a.ranges() - b.ranges()).into_range_set_blaze()
};
where T: Integer );
gen_ops_ex!(
<T>;
types ref RangeSetBlaze<T> => RangeSetBlaze<T>;
for ! call |a: &RangeSetBlaze<T>| {
(!a.ranges()).into_range_set_blaze()
};
where T: Integer );
impl<T: Integer> IntoIterator for RangeSetBlaze<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter {
option_range_front: None,
option_range_back: None,
into_iter: self.btree_map.into_iter(),
}
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct Iter<T, I>
where
T: Integer,
I: SortedDisjoint<T>,
{
iter: I,
option_range_front: Option<RangeInclusive<T>>,
option_range_back: Option<RangeInclusive<T>>,
}
impl<T: Integer, I> FusedIterator for Iter<T, I> where I: SortedDisjoint<T> + FusedIterator {}
impl<T: Integer, I> Iterator for Iter<T, I>
where
I: SortedDisjoint<T>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
let range = self
.option_range_front
.take()
.or_else(|| self.iter.next())
.or_else(|| self.option_range_back.take())?;
let (start, end) = range.into_inner();
debug_assert!(start <= end && end <= T::safe_max_value());
if start < end {
self.option_range_front = Some(start + T::one()..=end);
}
Some(start)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, _high) = self.iter.size_hint();
(low, None)
}
}
impl<T: Integer, I> DoubleEndedIterator for Iter<T, I>
where
I: SortedDisjoint<T> + DoubleEndedIterator,
{
fn next_back(&mut self) -> Option<Self::Item> {
let range = self
.option_range_back
.take()
.or_else(|| self.iter.next_back())
.or_else(|| self.option_range_front.take())?;
let (start, end) = range.into_inner();
debug_assert!(start <= end && end <= T::safe_max_value());
if start < end {
self.option_range_back = Some(start..=end - T::one());
}
Some(end)
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug)]
pub struct IntoIter<T: Integer> {
option_range_front: Option<RangeInclusive<T>>,
option_range_back: Option<RangeInclusive<T>>,
into_iter: alloc::collections::btree_map::IntoIter<T, T>,
}
impl<T: Integer> FusedIterator for IntoIter<T> {}
impl<T: Integer> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let range = self
.option_range_front
.take()
.or_else(|| self.into_iter.next().map(|(start, end)| start..=end))
.or_else(|| self.option_range_back.take())?;
let (start, end) = range.into_inner();
debug_assert!(start <= end && end <= T::safe_max_value());
if start < end {
self.option_range_front = Some(start + T::one()..=end);
}
Some(start)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, _high) = self.into_iter.size_hint();
(low, None)
}
}
impl<T: Integer> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
let range = self
.option_range_back
.take()
.or_else(|| self.into_iter.next_back().map(|(start, end)| start..=end))
.or_else(|| self.option_range_front.take())?;
let (start, end) = range.into_inner();
debug_assert!(start <= end && end <= T::safe_max_value());
if start < end {
self.option_range_back = Some(start..=end - T::one());
}
Some(end)
}
}
impl<T: Integer> Extend<T> for RangeSetBlaze<T> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
let iter = iter.into_iter();
for range in UnsortedDisjoint::from(iter.map(|x| x..=x)) {
self.internal_add(range);
}
}
}
impl<T: Integer> BitOrAssign<&RangeSetBlaze<T>> for RangeSetBlaze<T> {
fn bitor_assign(&mut self, other: &Self) {
let a_len = self.ranges_len();
if a_len == 0 {
*self = other.clone();
return;
}
let b_len = other.ranges_len();
if b_len * (a_len.ilog2() as usize + 1) < a_len + b_len {
self.extend(other.ranges());
} else {
*self = (self.ranges() | other.ranges()).into_range_set_blaze();
}
}
}
impl<T: Integer> BitOrAssign<RangeSetBlaze<T>> for RangeSetBlaze<T> {
fn bitor_assign(&mut self, mut other: Self) {
let a_len = self.ranges_len();
let b_len = other.ranges_len();
if b_len <= a_len {
*self |= &other;
} else {
other |= &*self;
*self = other;
}
}
}
impl<T: Integer> BitOr<RangeSetBlaze<T>> for RangeSetBlaze<T> {
type Output = RangeSetBlaze<T>;
fn bitor(mut self, other: Self) -> RangeSetBlaze<T> {
self |= other;
self
}
}
impl<T: Integer> BitOr<&RangeSetBlaze<T>> for RangeSetBlaze<T> {
type Output = RangeSetBlaze<T>;
fn bitor(mut self, other: &Self) -> RangeSetBlaze<T> {
self |= other;
self
}
}
impl<T: Integer> BitOr<RangeSetBlaze<T>> for &RangeSetBlaze<T> {
type Output = RangeSetBlaze<T>;
fn bitor(self, mut other: RangeSetBlaze<T>) -> RangeSetBlaze<T> {
other |= self;
other
}
}
impl<T: Integer> BitOr<&RangeSetBlaze<T>> for &RangeSetBlaze<T> {
type Output = RangeSetBlaze<T>;
fn bitor(self, other: &RangeSetBlaze<T>) -> RangeSetBlaze<T> {
(self.ranges() | other.ranges()).into_range_set_blaze()
}
}
impl<T: Integer> Extend<RangeInclusive<T>> for RangeSetBlaze<T> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = RangeInclusive<T>>,
{
let iter = iter.into_iter();
for range in iter {
self.internal_add(range);
}
}
}
impl<T: Integer> Ord for RangeSetBlaze<T> {
#[inline]
fn cmp(&self, other: &RangeSetBlaze<T>) -> Ordering {
let mut a = self.ranges();
let mut b = other.ranges();
let mut a_rx = a.next();
let mut b_rx = b.next();
loop {
match (a_rx.clone(), b_rx.clone()) {
(Some(a_r), Some(b_r)) => {
let cmp_start = a_r.start().cmp(b_r.start());
if cmp_start != Ordering::Equal {
return cmp_start;
}
let cmp_end = a_r.end().cmp(b_r.end());
match cmp_end {
Ordering::Equal => {
a_rx = a.next();
b_rx = b.next();
}
Ordering::Less => {
a_rx = a.next();
b_rx = Some(*a_r.end() + T::one()..=*b_r.end());
}
Ordering::Greater => {
a_rx = Some(*b_r.end() + T::one()..=*a_r.end());
b_rx = b.next();
}
}
}
(Some(_), None) => return Ordering::Greater,
(None, Some(_)) => return Ordering::Less,
(None, None) => return Ordering::Equal,
}
}
}
}
impl<T: Integer> PartialOrd for RangeSetBlaze<T> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T: Integer> Eq for RangeSetBlaze<T> {}
impl<T: Integer, I: SortedStarts<T>> SortedStarts<T> for UnionIter<T, I> {}
impl<T: Integer, I: SortedStarts<T>> SortedDisjoint<T> for UnionIter<T, I> {}
impl<T: Integer, I: SortedDisjoint<T>> SortedStarts<T> for NotIter<T, I> {}
impl<T: Integer, I: SortedDisjoint<T>> SortedDisjoint<T> for NotIter<T, I> {}
impl<T: Integer, I: SortedDisjoint<T>> SortedStarts<T> for Tee<I> {}
impl<T: Integer, I: SortedDisjoint<T>> SortedDisjoint<T> for Tee<I> {}
#[cfg(feature = "std")]
use std::{
fs::File,
io::{self, BufRead, BufReader},
path::Path,
};
#[cfg(feature = "std")]
#[doc(hidden)]
pub fn demo_read_ranges_from_file<P, T>(path: P) -> io::Result<RangeSetBlaze<T>>
where
P: AsRef<Path>,
T: FromStr + Integer,
{
let lines = BufReader::new(File::open(&path)?).lines();
let mut set = RangeSetBlaze::new();
for line in lines {
let line = line?;
let mut split = line.split('\t');
let start = split
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Missing start of range"))?
.parse::<T>()
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid start of range"))?;
let end = split
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Missing end of range"))?
.parse::<T>()
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid end of range"))?;
set.ranges_insert(start..=end);
}
Ok(set)
}