use core::borrow::Borrow;
use core::fmt::{self, Debug};
use core::iter::{DoubleEndedIterator, FromIterator};
use core::ops::{BitAnd, BitOr, RangeInclusive};
#[cfg(feature = "serde1")]
use core::marker::PhantomData;
#[cfg(feature = "serde1")]
use serde::{
de::{Deserialize, Deserializer, SeqAccess, Visitor},
ser::{Serialize, Serializer},
};
use crate::std_ext::*;
use crate::RangeInclusiveMap;
pub type Intersection<'a, T> = crate::operations::Intersection<'a, RangeInclusive<T>, Iter<'a, T>>;
pub type Union<'a, T> = crate::operations::Union<'a, RangeInclusive<T>, Iter<'a, T>>;
#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct RangeInclusiveSet<T, StepFnsT = T> {
rm: RangeInclusiveMap<T, (), StepFnsT>,
}
impl<T, StepFnsT> Default for RangeInclusiveSet<T, StepFnsT> {
fn default() -> Self {
Self {
rm: RangeInclusiveMap::default(),
}
}
}
impl<T> RangeInclusiveSet<T, T>
where
T: Ord + Clone + StepLite,
{
#[cfg(feature = "const_fn")]
pub const fn new() -> Self {
Self::new_with_step_fns()
}
#[cfg(not(feature = "const_fn"))]
pub fn new() -> Self {
Self::new_with_step_fns()
}
}
impl<T, StepFnsT> RangeInclusiveSet<T, StepFnsT>
where
T: Ord + Clone,
StepFnsT: StepFns<T>,
{
#[cfg(not(feature = "const_fn"))]
pub fn new_with_step_fns() -> Self {
Self {
rm: RangeInclusiveMap::new_with_step_fns(),
}
}
#[cfg(feature = "const_fn")]
pub const fn new_with_step_fns() -> Self {
Self {
rm: RangeInclusiveMap::new_with_step_fns(),
}
}
pub fn get(&self, value: &T) -> Option<&RangeInclusive<T>> {
self.rm.get_key_value(value).map(|(range, _)| range)
}
pub fn contains(&self, value: &T) -> bool {
self.rm.contains_key(value)
}
pub fn iter(&self) -> Iter<'_, T> {
Iter {
inner: self.rm.iter(),
}
}
pub fn clear(&mut self) {
self.rm.clear();
}
pub fn len(&self) -> usize {
self.rm.len()
}
pub fn is_empty(&self) -> bool {
self.rm.is_empty()
}
pub fn insert(&mut self, range: RangeInclusive<T>) {
self.rm.insert(range, ());
}
pub fn remove(&mut self, range: RangeInclusive<T>) {
self.rm.remove(range);
}
pub fn gaps<'a>(&'a self, outer_range: &'a RangeInclusive<T>) -> Gaps<'a, T, StepFnsT> {
Gaps {
inner: self.rm.gaps(outer_range),
}
}
pub fn overlapping<R: Borrow<RangeInclusive<T>>>(&self, range: R) -> Overlapping<T, R> {
Overlapping {
inner: self.rm.overlapping(range),
}
}
pub fn overlaps(&self, range: &RangeInclusive<T>) -> bool {
self.overlapping(range).next().is_some()
}
pub fn first(&self) -> Option<&RangeInclusive<T>> {
self.rm.first_range_value().map(|(range, _)| range)
}
pub fn last(&self) -> Option<&RangeInclusive<T>> {
self.rm.last_range_value().map(|(range, _)| range)
}
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T> {
Union::new(self.iter(), other.iter())
}
pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T> {
Intersection::new(self.iter(), other.iter())
}
}
pub struct Iter<'a, T> {
inner: super::inclusive_map::Iter<'a, T, ()>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a RangeInclusive<T>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(range, _)| range)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, K> DoubleEndedIterator for Iter<'a, K>
where
K: 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(range, _)| range)
}
}
pub struct IntoIter<T> {
inner: super::inclusive_map::IntoIter<T, ()>,
}
impl<T> IntoIterator for RangeInclusiveSet<T> {
type Item = RangeInclusive<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.rm.into_iter(),
}
}
}
impl<T> Iterator for IntoIter<T> {
type Item = RangeInclusive<T>;
fn next(&mut self) -> Option<RangeInclusive<T>> {
self.inner.next().map(|(range, _)| range)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K> DoubleEndedIterator for IntoIter<K> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(range, _)| range)
}
}
impl<T: Debug> Debug for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> FromIterator<RangeInclusive<T>> for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite,
{
fn from_iter<I: IntoIterator<Item = RangeInclusive<T>>>(iter: I) -> Self {
let mut range_set = RangeInclusiveSet::new();
range_set.extend(iter);
range_set
}
}
impl<T> Extend<RangeInclusive<T>> for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite,
{
fn extend<I: IntoIterator<Item = RangeInclusive<T>>>(&mut self, iter: I) {
iter.into_iter().for_each(move |range| {
self.insert(range);
})
}
}
#[cfg(feature = "serde1")]
impl<T> Serialize for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite + Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.rm.btm.len()))?;
for range in self.iter() {
seq.serialize_element(&(&range.start(), &range.end()))?;
}
seq.end()
}
}
#[cfg(feature = "serde1")]
impl<'de, T> Deserialize<'de> for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite + Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(RangeInclusiveSetVisitor::new())
}
}
#[cfg(feature = "serde1")]
struct RangeInclusiveSetVisitor<T> {
marker: PhantomData<fn() -> RangeInclusiveSet<T>>,
}
#[cfg(feature = "serde1")]
impl<T> RangeInclusiveSetVisitor<T> {
fn new() -> Self {
RangeInclusiveSetVisitor {
marker: PhantomData,
}
}
}
#[cfg(feature = "serde1")]
impl<'de, T> Visitor<'de> for RangeInclusiveSetVisitor<T>
where
T: Ord + Clone + StepLite + Deserialize<'de>,
{
type Value = RangeInclusiveSet<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("RangeInclusiveSet")
}
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut range_inclusive_set = RangeInclusiveSet::new();
while let Some((start, end)) = access.next_element()? {
range_inclusive_set.insert(start..=end);
}
Ok(range_inclusive_set)
}
}
pub struct Gaps<'a, T, StepFnsT> {
inner: crate::inclusive_map::Gaps<'a, T, (), StepFnsT>,
}
impl<'a, T, StepFnsT> core::iter::FusedIterator for Gaps<'a, T, StepFnsT>
where
T: Ord + Clone,
StepFnsT: StepFns<T>,
{
}
impl<'a, T, StepFnsT> Iterator for Gaps<'a, T, StepFnsT>
where
T: Ord + Clone,
StepFnsT: StepFns<T>,
{
type Item = RangeInclusive<T>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct Overlapping<'a, T, R: Borrow<RangeInclusive<T>> = &'a RangeInclusive<T>> {
inner: crate::inclusive_map::Overlapping<'a, T, (), R>,
}
impl<'a, T, R: Borrow<RangeInclusive<T>>> core::iter::FusedIterator for Overlapping<'a, T, R> where
T: Ord + Clone
{
}
impl<'a, T, R: Borrow<RangeInclusive<T>>> Iterator for Overlapping<'a, T, R>
where
T: Ord + Clone,
{
type Item = &'a RangeInclusive<T>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, _v)| k)
}
}
impl<'a, T, R: Borrow<RangeInclusive<T>>> DoubleEndedIterator for Overlapping<'a, T, R>
where
T: Ord + Clone,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(k, _v)| k)
}
}
impl<T: Ord + Clone + StepLite, const N: usize> From<[RangeInclusive<T>; N]>
for RangeInclusiveSet<T>
{
fn from(value: [RangeInclusive<T>; N]) -> Self {
let mut set = Self::new();
for value in IntoIterator::into_iter(value) {
set.insert(value);
}
set
}
}
#[macro_export]
macro_rules! range_inclusive_set {
($($range:expr),* $(,)?) => {{
$crate::RangeInclusiveSet::from([$($range),*])
}};
}
impl<T: Ord + Clone + StepLite> BitAnd for &RangeInclusiveSet<T> {
type Output = RangeInclusiveSet<T>;
fn bitand(self, other: Self) -> Self::Output {
self.intersection(other).collect()
}
}
impl<T: Ord + Clone + StepLite> BitOr for &RangeInclusiveSet<T> {
type Output = RangeInclusiveSet<T>;
fn bitor(self, other: Self) -> Self::Output {
self.union(other).collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc as std;
use alloc::{format, vec, vec::Vec};
use proptest::prelude::*;
use test_strategy::proptest;
impl<T> Arbitrary for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite + Debug + Arbitrary + 'static,
{
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_parameters: Self::Parameters) -> Self::Strategy {
any::<Vec<RangeInclusive<T>>>()
.prop_map(|ranges| ranges.into_iter().collect::<RangeInclusiveSet<T>>())
.boxed()
}
}
#[proptest]
fn test_first(set: RangeInclusiveSet<u64>) {
assert_eq!(set.first(), set.iter().min_by_key(|range| range.start()));
}
#[proptest]
#[allow(clippy::len_zero)]
fn test_len(mut map: RangeInclusiveSet<u64>) {
assert_eq!(map.len(), map.iter().count());
assert_eq!(map.is_empty(), map.len() == 0);
map.clear();
assert_eq!(map.len(), 0);
assert!(map.is_empty());
assert_eq!(map.iter().count(), 0);
}
#[proptest]
fn test_last(set: RangeInclusiveSet<u64>) {
assert_eq!(set.last(), set.iter().max_by_key(|range| range.end()));
}
#[proptest]
fn test_iter_reversible(set: RangeInclusiveSet<u64>) {
let forward: Vec<_> = set.iter().collect();
let mut backward: Vec<_> = set.iter().rev().collect();
backward.reverse();
assert_eq!(forward, backward);
}
#[proptest]
fn test_into_iter_reversible(set: RangeInclusiveSet<u64>) {
let forward: Vec<_> = set.clone().into_iter().collect();
let mut backward: Vec<_> = set.into_iter().rev().collect();
backward.reverse();
assert_eq!(forward, backward);
}
#[proptest]
fn test_overlapping_reversible(set: RangeInclusiveSet<u64>, range: RangeInclusive<u64>) {
let forward: Vec<_> = set.overlapping(&range).collect();
let mut backward: Vec<_> = set.overlapping(&range).rev().collect();
backward.reverse();
assert_eq!(forward, backward);
}
fn filter_ranges<T: Ord>(ranges: Vec<RangeInclusive<T>>) -> Vec<RangeInclusive<T>> {
ranges
.into_iter()
.filter(|range| range.start() != range.end())
.collect()
}
#[proptest]
fn test_arbitrary_set_u8(ranges: Vec<RangeInclusive<u8>>) {
let ranges: Vec<_> = filter_ranges(ranges);
let set = ranges
.iter()
.fold(RangeInclusiveSet::new(), |mut set, range| {
set.insert(range.clone());
set
});
for value in 0..u8::MAX {
assert_eq!(
set.contains(&value),
ranges.iter().any(|range| range.contains(&value))
);
}
}
#[proptest]
#[allow(deprecated)]
fn test_hash(left: RangeInclusiveSet<u64>, right: RangeInclusiveSet<u64>) {
use core::hash::{Hash, Hasher, SipHasher};
let hash = |set: &RangeInclusiveSet<_>| {
let mut hasher = SipHasher::new();
set.hash(&mut hasher);
hasher.finish()
};
if left == right {
assert!(
hash(&left) == hash(&right),
"if two values are equal, their hash must be equal"
);
}
if hash(&left) != hash(&right) {
assert!(
left != right,
"if two value's hashes are not equal, they must not be equal"
);
}
}
#[proptest]
fn test_ord(left: RangeInclusiveSet<u64>, right: RangeInclusiveSet<u64>) {
assert_eq!(
left == right,
left.cmp(&right).is_eq(),
"ordering and equality must match"
);
assert_eq!(
left.cmp(&right),
left.partial_cmp(&right).unwrap(),
"ordering is total for ordered parameters"
);
}
#[test]
fn test_from_array() {
let mut set = RangeInclusiveSet::new();
set.insert(0..=100);
set.insert(200..=300);
assert_eq!(set, RangeInclusiveSet::from([0..=100, 200..=300]));
}
#[test]
fn test_macro() {
assert_eq!(range_inclusive_set![], RangeInclusiveSet::<i64>::default());
assert_eq!(
range_inclusive_set![0..=100, 200..=300, 400..=500],
[0..=100, 200..=300, 400..=500].iter().cloned().collect(),
);
}
#[proptest]
fn test_union_overlaps_u8(left: RangeInclusiveSet<u8>, right: RangeInclusiveSet<u8>) {
let mut union = RangeInclusiveSet::new();
for range in left.union(&right) {
assert!(union.overlapping(&range).next().is_none());
union.insert(range);
}
}
#[proptest]
fn test_union_contains_u8(left: RangeInclusiveSet<u8>, right: RangeInclusiveSet<u8>) {
let union = (&left) | (&right);
for value in 0..u8::MAX {
assert_eq!(
union.contains(&value),
left.contains(&value) || right.contains(&value)
);
}
}
#[proptest]
fn test_intersection_contains_u8(left: RangeInclusiveSet<u8>, right: RangeInclusiveSet<u8>) {
let intersection = (&left) & (&right);
for value in 0..u8::MAX {
assert_eq!(
intersection.contains(&value),
left.contains(&value) && right.contains(&value)
);
}
}
#[proptest]
fn test_intersection_overlaps_u8(left: RangeInclusiveSet<u8>, right: RangeInclusiveSet<u8>) {
let mut union = RangeInclusiveSet::new();
for range in left.intersection(&right) {
assert!(union.overlapping(&range).next().is_none());
union.insert(range);
}
}
trait RangeInclusiveSetExt<T> {
fn to_vec(&self) -> Vec<RangeInclusive<T>>;
}
impl<T> RangeInclusiveSetExt<T> for RangeInclusiveSet<T>
where
T: Ord + Clone + StepLite,
{
fn to_vec(&self) -> Vec<RangeInclusive<T>> {
self.iter().cloned().collect()
}
}
#[test]
fn empty_set_is_empty() {
let range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
assert_eq!(range_set.to_vec(), vec![]);
}
#[test]
fn insert_into_empty_map() {
let mut range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
range_set.insert(0..=50);
assert_eq!(range_set.to_vec(), vec![0..=50]);
}
#[test]
fn remove_partially_overlapping() {
let mut range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
range_set.insert(0..=50);
range_set.remove(25..=75);
assert_eq!(range_set.to_vec(), vec![0..=24]);
}
#[test]
fn gaps_between_items_floating_inside_outer_range() {
let mut range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
range_set.insert(5..=6);
range_set.insert(2..=3);
let outer_range = 1..=8;
let mut gaps = range_set.gaps(&outer_range);
assert_eq!(gaps.next(), Some(1..=1));
assert_eq!(gaps.next(), Some(4..=4));
assert_eq!(gaps.next(), Some(7..=8));
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
}
#[test]
fn overlapping_partial_edges_complete_middle() {
let mut range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
range_set.insert(0..=1);
range_set.insert(3..=4);
range_set.insert(6..=7);
let query_range = 1..=6;
let mut overlapping = range_set.overlapping(&query_range);
assert_eq!(overlapping.next(), Some(&(0..=1)));
assert_eq!(overlapping.next(), Some(&(3..=4)));
assert_eq!(overlapping.next(), Some(&(6..=7)));
assert_eq!(overlapping.next(), None);
assert_eq!(overlapping.next(), None);
}
#[test]
fn set_debug_repr_looks_right() {
let mut set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
assert_eq!(format!("{:?}", set), "{}");
set.insert(2..=5);
assert_eq!(format!("{:?}", set), "{2..=5}");
set.insert(7..=8);
set.insert(10..=11);
assert_eq!(format!("{:?}", set), "{2..=5, 7..=8, 10..=11}");
}
#[test]
fn always_default() {
struct NoDefault;
RangeInclusiveSet::<NoDefault>::default();
}
#[cfg(feature = "serde1")]
#[test]
fn serialization() {
let mut range_set: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
range_set.insert(1..=3);
range_set.insert(5..=7);
let output = serde_json::to_string(&range_set).expect("Failed to serialize");
assert_eq!(output, "[[1,3],[5,7]]");
}
#[cfg(feature = "serde1")]
#[test]
fn deserialization() {
let input = "[[1,3],[5,7]]";
let range_set: RangeInclusiveSet<u32> =
serde_json::from_str(input).expect("Failed to deserialize");
let reserialized = serde_json::to_string(&range_set).expect("Failed to re-serialize");
assert_eq!(reserialized, input);
}
#[cfg(feature = "const_fn")]
const _SET: RangeInclusiveSet<u32> = RangeInclusiveSet::new();
#[cfg(feature = "const_fn")]
const _SET2: RangeInclusiveSet<u32> = RangeInclusiveSet::new_with_step_fns();
}