#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)]
#![allow(clippy::doc_markdown, clippy::redundant_pub_crate)]
#![cfg_attr(rustc_1_36, no_std)]
#[cfg(rustc_1_36)]
extern crate alloc;
#[cfg(not(rustc_1_36))]
extern crate std as alloc;
#[cfg(not(rustc_1_36))]
extern crate std as core;
mod element;
mod nestable;
use crate::{
element::{Element, ParentElements},
nestable::Nestable,
};
use alloc::{borrow::ToOwned, collections::VecDeque, vec::Vec};
use core::{
borrow::Borrow,
cmp::{min, Ordering},
hint::unreachable_unchecked,
iter::{once, Chain, FromIterator, FusedIterator, Iterator, Once},
marker::PhantomData,
mem,
num::NonZeroUsize,
ops::RangeBounds,
};
#[derive(Debug)]
pub struct OverlappingElement<'a, R, S, T>
where
R: RangeBounds<T> + 'a,
S: RangeBounds<T> + 'a,
T: Ord + 'a,
{
pub value: &'a R,
sublist_elements: &'a [Element<R, T>],
query: &'a S,
_marker: PhantomData<T>,
}
impl<'a, R, S, T> OverlappingElement<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
#[must_use]
pub fn sublist(&self) -> Overlapping<'a, R, S, T> {
Overlapping::new(self.sublist_elements, self.query)
}
}
impl<'a, R, S, T> IntoIterator for OverlappingElement<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
type Item = Self;
type IntoIter = Chain<Once<Self::Item>, Overlapping<'a, R, S, T>>;
#[must_use]
fn into_iter(self) -> Self::IntoIter {
once(Self {
value: self.value,
sublist_elements: &[],
query: self.query,
_marker: PhantomData,
})
.chain(self.sublist())
}
}
#[derive(Debug)]
pub struct Overlapping<'a, R, S, T>
where
R: RangeBounds<T> + 'a,
S: RangeBounds<T> + 'a,
T: Ord + 'a,
{
elements: &'a [Element<R, T>],
query: &'a S,
}
impl<'a, R, S, T> Overlapping<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
fn new(elements: &'a [Element<R, T>], query: &'a S) -> Self {
Overlapping { elements, query }
}
}
impl<'a, R, S, T> Iterator for Overlapping<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
type Item = OverlappingElement<'a, R, S, T>;
fn next(&mut self) -> Option<Self::Item> {
while !self.elements.is_empty() {
let element = unsafe {
self.elements.get_unchecked(0)
};
if element.value.overlapping(self.query) {
let sublist_elements = unsafe {
self.elements.get_unchecked(1..=element.sublist_len)
};
self.elements = unsafe {
self.elements.get_unchecked((element.sublist_len + 1)..)
};
return Some(OverlappingElement {
value: &element.value,
sublist_elements,
query: self.query,
_marker: PhantomData,
});
}
match self.query.ordering(&element.value) {
Ordering::Greater | Ordering::Equal => {
let mut index = 0;
let mut size = self.elements.len();
if size != 0 {
while size > 1 {
let half = size / 2;
let mid = index + half;
let mid_element = unsafe {
self.elements.top_most_parent_element(mid)
};
index = match if mid_element.value.overlapping(self.query) {
Ordering::Greater
} else {
mid_element.value.ordering(self.query)
} {
Ordering::Greater => index,
Ordering::Less | Ordering::Equal => mid,
};
size -= half;
}
let index_element = unsafe {
self.elements.get_unchecked(index)
};
match if index_element.value.overlapping(self.query) {
Ordering::Greater
} else {
index_element.value.ordering(self.query)
} {
Ordering::Less => {
index += 1;
}
Ordering::Greater | Ordering::Equal => {}
}
}
self.elements = unsafe {
self.elements.get_unchecked(index..)
};
}
Ordering::Less => {
self.elements = &[];
}
}
}
None
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(min(1, self.elements.len()), Some(self.elements.len()))
}
}
impl<'a, R, S, T> DoubleEndedIterator for Overlapping<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
fn next_back(&mut self) -> Option<Self::Item> {
while !self.elements.is_empty() {
let (element, index) = unsafe {
self.elements
.top_most_parent_element_with_index(self.elements.len() - 1)
};
if element.value.overlapping(self.query) {
let sublist_elements = unsafe {
self.elements.get_unchecked((index + 1)..)
};
self.elements = unsafe {
self.elements.get_unchecked(..index)
};
return Some(OverlappingElement {
value: &element.value,
sublist_elements,
query: self.query,
_marker: PhantomData,
});
}
match self.query.ordering(&element.value) {
Ordering::Less | Ordering::Equal => {
let mut index = 0;
let mut size = self.elements.len();
if size != 0 {
while size > 1 {
let half = size / 2;
let mid = index + half;
let mid_element = unsafe {
self.elements.top_most_parent_element(mid)
};
index = match if mid_element.value.overlapping(self.query) {
Ordering::Less
} else {
mid_element.value.ordering(self.query)
} {
Ordering::Greater => index,
Ordering::Less | Ordering::Equal => mid,
};
size -= half;
}
let index_element = unsafe {
self.elements.get_unchecked(index)
};
match if index_element.value.overlapping(self.query) {
Ordering::Less
} else {
index_element.value.ordering(self.query)
} {
Ordering::Less => {
index += 1;
}
Ordering::Greater | Ordering::Equal => {}
}
}
self.elements = unsafe {
self.elements.get_unchecked(..index)
};
}
Ordering::Greater => {
self.elements = &[];
}
}
}
None
}
}
impl<'a, R, S, T> FusedIterator for Overlapping<'a, R, S, T>
where
R: RangeBounds<T>,
S: RangeBounds<T>,
T: Ord,
{
}
#[derive(Debug)]
pub struct IterElement<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
pub value: R,
sublist_elements: VecDeque<Element<R, T>>,
}
impl<R, T> IterElement<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
pub fn sublist(self) -> Iter<R, T> {
Iter {
elements: self.sublist_elements,
}
}
}
impl<R, T> IntoIterator for IterElement<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
type Item = Self;
type IntoIter = Chain<Once<Self::Item>, Iter<R, T>>;
fn into_iter(self) -> Self::IntoIter {
once(Self {
value: self.value,
sublist_elements: VecDeque::new(),
})
.chain(Iter {
elements: self.sublist_elements,
})
}
}
#[derive(Debug)]
pub struct Iter<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
elements: VecDeque<Element<R, T>>,
}
impl<R, T> Iterator for Iter<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
type Item = IterElement<R, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.elements.is_empty() {
return None;
}
let element = self.elements.pop_front().unwrap();
let remaining_elements = self.elements.split_off(element.sublist_len);
Some(IterElement {
value: element.value,
sublist_elements: mem::replace(&mut self.elements, remaining_elements),
})
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(min(1, self.elements.len()), Some(self.elements.len()))
}
}
impl<R, T> DoubleEndedIterator for Iter<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.elements.is_empty() {
return None;
}
let mut sublist_elements = VecDeque::new();
let element = loop {
let parent_element = self.elements.pop_back().unwrap();
if let Some(offset) = parent_element.parent_offset {
if offset.get() > self.elements.len() {
break parent_element;
}
sublist_elements.push_front(parent_element);
self.elements
.split_off(self.elements.len() - offset.get() + 1)
.into_iter()
.for_each(|element| sublist_elements.push_front(element));
} else {
break parent_element;
}
};
Some(IterElement {
value: element.value,
sublist_elements,
})
}
}
impl<R, T> FusedIterator for Iter<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
}
#[derive(Debug)]
pub struct NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
elements: Vec<Element<R, T>>,
}
impl<R, T> NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
#[must_use]
pub fn new() -> Self {
Self {
elements: Vec::new(),
}
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
elements: Vec::with_capacity(capacity),
}
}
#[must_use]
pub fn len(&self) -> usize {
self.elements.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
#[must_use]
pub fn capacity(&self) -> usize {
self.elements.capacity()
}
#[must_use]
pub fn overlapping<'a, S>(&'a self, query: &'a S) -> Overlapping<'a, R, S, T>
where
S: RangeBounds<T>,
{
Overlapping::new(&self.elements, query)
}
fn insert_at(&mut self, index: usize, value: R) {
let mut len = 0;
let mut inner_indices = index..self.elements.len();
while let Some(inner_index) = inner_indices.next() {
let inner_element = unsafe {
self.elements.get_unchecked_mut(inner_index)
};
if Nestable::contains(&value, &inner_element.value) {
len += inner_element.sublist_len + 1;
inner_element.parent_offset = Some(unsafe {
NonZeroUsize::new_unchecked(inner_index - index + 1)
});
if inner_element.sublist_len > 0 {
inner_indices.nth(inner_element.sublist_len - 1);
}
} else {
break;
}
}
let mut direct_parent_index = None;
if index > 0 {
let mut parent_index = index - 1;
loop {
let parent_element = unsafe { self.elements.get_unchecked_mut(parent_index) };
let current_parent_offset = parent_element.parent_offset;
if Nestable::contains(&parent_element.value, &value) {
if direct_parent_index.is_none() {
direct_parent_index = Some(parent_index);
}
let current_parent_sublist_len = parent_element.sublist_len;
parent_element.sublist_len += 1;
let mut child_index = index;
while child_index <= parent_index + current_parent_sublist_len {
let child_element = unsafe {
self.elements.get_unchecked_mut(child_index)
};
child_element.parent_offset = Some(unsafe {
NonZeroUsize::new_unchecked(
child_element.parent_offset.unwrap().get() + 1,
)
});
child_index += child_element.sublist_len + 1;
}
}
if let Some(offset) = current_parent_offset {
parent_index -= offset.get();
} else {
break;
}
}
}
self.elements.insert(
index,
Element {
value,
sublist_len: len,
parent_offset: direct_parent_index.map(|parent_index| unsafe {
NonZeroUsize::new_unchecked(index - parent_index)
}),
_marker: PhantomData,
},
);
}
pub fn insert(&mut self, value: R) {
let index = match self
.elements
.binary_search_by(|element| element.value.ordering(&value))
{
Ok(index) | Err(index) => index,
};
self.insert_at(index, value);
}
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
Q: RangeBounds<T>,
R: Borrow<Q>,
{
match self
.elements
.binary_search_by(|element| element.value.ordering(Borrow::borrow(value)))
{
Ok(index) => {
let removed_element = unsafe {
self.elements.get_unchecked(index)
};
let removed_element_sublist_len = removed_element.sublist_len;
let removed_element_parent_offset = removed_element.parent_offset;
let mut child_index = index + 1;
while child_index <= index + removed_element_sublist_len {
let child_element = unsafe {
self.elements.get_unchecked_mut(child_index)
};
child_element.parent_offset =
removed_element_parent_offset.map(|offset| unsafe {
NonZeroUsize::new_unchecked(
offset.get() + child_element.parent_offset.unwrap().get() - 1,
)
});
child_index += child_element.sublist_len + 1;
}
if let Some(offset) = removed_element_parent_offset {
let mut parent_index = index - offset.get();
loop {
let parent_element = unsafe {
self.elements.get_unchecked_mut(parent_index)
};
parent_element.sublist_len -= 1;
if let Some(parent_offset) = parent_element.parent_offset {
parent_index -= parent_offset.get();
} else {
break;
}
}
}
self.elements.remove(index);
true
}
Err(_) => false,
}
}
}
impl<R, T> FromIterator<R> for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = R>,
{
let mut values = iter.into_iter().collect::<Vec<_>>();
values.sort_unstable_by(Nestable::ordering);
let mut elements: Vec<Element<R, T>> = Vec::with_capacity(values.len());
let mut sublist_indices: Vec<usize> = Vec::with_capacity(values.len());
for index in 0..values.len() {
let value = values.remove(0);
while !sublist_indices.is_empty() {
let sublist_index = sublist_indices.pop().unwrap_or_else(|| {
if cfg!(debug_assertions) {
unreachable!()
} else {
unsafe { unreachable_unchecked() }
}
});
let mut sublist_element = unsafe {
elements.get_unchecked_mut(sublist_index)
};
if Nestable::contains(&sublist_element.value, &value) {
sublist_indices.push(sublist_index);
break;
}
let len = index - sublist_index - 1;
sublist_element.sublist_len = len;
}
elements.push(Element {
value,
sublist_len: 0,
parent_offset: sublist_indices.last().map(|sublist_index| unsafe {
NonZeroUsize::new_unchecked(index - sublist_index)
}),
_marker: PhantomData,
});
sublist_indices.push(index);
}
for sublist_index in sublist_indices {
let len = elements.len() - sublist_index - 1;
unsafe {
elements.get_unchecked_mut(sublist_index)
}
.sublist_len = len;
}
Self { elements }
}
}
impl<R, T> IntoIterator for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
type Item = IterElement<R, T>;
type IntoIter = Iter<R, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
elements: VecDeque::from(self.elements),
}
}
}
impl<R, T> Extend<R> for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = R>,
{
let mut values: Vec<_> = iter.into_iter().collect();
values.sort_unstable_by(Nestable::ordering);
let mut index = 0;
for value in values {
let prev_index = index;
index = match self.elements[index..]
.binary_search_by(|element| element.value.ordering(&value))
{
Ok(index) | Err(index) => index,
};
self.insert_at(prev_index + index, value);
index += 1;
}
}
}
impl<R, T> From<Vec<R>> for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
#[inline]
fn from(v: Vec<R>) -> Self {
Self::from_iter(v)
}
}
impl<R, T> From<&'_ [R]> for NestedContainmentList<R, T>
where
R: RangeBounds<T> + Clone,
T: Ord,
{
#[inline]
fn from(s: &[R]) -> Self {
Self::from_iter(s.to_owned())
}
}
#[cfg(rustc_1_41)]
#[cfg_attr(feature = "doc_item", doc_item::since(content="1.41.0"))]
impl<R, T> From<NestedContainmentList<R, T>> for Vec<R>
where
R: RangeBounds<T>,
T: Ord,
{
#[inline]
fn from(nclist: NestedContainmentList<R, T>) -> Self {
nclist
.elements
.into_iter()
.map(|element| element.value)
.collect()
}
}
#[cfg(not(rustc_1_41))]
impl<R, T> Into<Vec<R>> for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
#[inline]
fn into(self) -> Vec<R> {
self.elements
.into_iter()
.map(|element| element.value)
.collect()
}
}
impl<R, T> Default for NestedContainmentList<R, T>
where
R: RangeBounds<T>,
T: Ord,
{
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use crate::NestedContainmentList;
use alloc::{vec, vec::Vec};
use claim::assert_none;
use core::{iter::FromIterator, ops::Range};
#[test]
fn new() {
let nclist = NestedContainmentList::<Range<usize>, usize>::new();
assert_none!(nclist.overlapping(&(..)).next());
}
#[test]
fn default() {
let nclist = NestedContainmentList::<Range<usize>, usize>::default();
assert_none!(nclist.overlapping(&(..)).next());
}
#[test]
fn len() {
let mut nclist = NestedContainmentList::new();
assert_eq!(nclist.len(), 0);
nclist.insert(1..5);
assert_eq!(nclist.len(), 1);
}
#[test]
fn is_empty() {
assert!(NestedContainmentList::<Range<usize>, usize>::new().is_empty());
}
#[test]
fn is_not_empty() {
assert!(!NestedContainmentList::from_iter(vec![1..2]).is_empty());
}
#[test]
fn capacity() {
let nclist = NestedContainmentList::<Range<usize>, usize>::with_capacity(10);
assert_eq!(nclist.capacity(), 10);
}
#[test]
fn insert_on_empty() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
let mut sublist = nclist.overlapping(&(..));
assert_eq!(sublist.next().unwrap().value, &(1..5));
assert_none!(sublist.next());
}
#[test]
fn insert_contained() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
nclist.insert(2..4);
let mut sublist = nclist.overlapping(&(..));
let sublist_first_element = sublist.next().unwrap();
assert_eq!(sublist_first_element.value, &(1..5));
let mut sublist_first_element_sublist = sublist_first_element.sublist();
assert_eq!(sublist_first_element_sublist.next().unwrap().value, &(2..4));
assert_none!(sublist_first_element_sublist.next());
assert_none!(sublist.next());
}
#[test]
fn insert_containing() {
let mut nclist = NestedContainmentList::new();
nclist.insert(2..4);
nclist.insert(1..5);
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
assert_eq!(first_sublist_element_sublist.next().unwrap().value, &(2..4));
assert_none!(first_sublist_element_sublist.next());
assert_none!(sublist.next());
}
#[test]
fn insert_contained_not_at_end() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
nclist.insert(6..10);
nclist.insert(2..4);
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
assert_eq!(first_sublist_element_sublist.next().unwrap().value, &(2..4));
assert_none!(first_sublist_element_sublist.next());
assert_eq!(sublist.next().unwrap().value, &(6..10));
assert_none!(sublist.next());
}
#[test]
fn insert_contained_and_containing() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
nclist.insert(3..4);
nclist.insert(2..4);
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
let second_sublist_element = first_sublist_element_sublist.next().unwrap();
assert_eq!(second_sublist_element.value, &(2..4));
let mut second_sublist_element_sublist = second_sublist_element.sublist();
assert_eq!(
second_sublist_element_sublist.next().unwrap().value,
&(3..4)
);
assert_none!(first_sublist_element_sublist.next());
assert_none!(sublist.next());
}
#[test]
fn insert_equal() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
nclist.insert(1..5);
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
assert_eq!(first_sublist_element_sublist.next().unwrap().value, &(1..5));
assert_none!(first_sublist_element_sublist.next());
assert_none!(sublist.next());
}
#[test]
fn insert_disjoint() {
let mut nclist = NestedContainmentList::new();
nclist.insert(1..5);
nclist.insert(6..10);
let mut sublist = nclist.overlapping(&(..));
assert_eq!(sublist.next().unwrap().value, &(1..5));
assert_eq!(sublist.next().unwrap().value, &(6..10));
assert_none!(sublist.next());
}
#[test]
fn insert_into_second_sublist() {
let mut nclist = NestedContainmentList::from_iter(vec![1..4, 2..3, 5..9]);
nclist.insert(6..8);
let mut sublist = nclist.overlapping(&(..));
assert_eq!(sublist.next().unwrap().value, &(1..4));
let second_element = sublist.next().unwrap();
assert_eq!(second_element.value, &(5..9));
assert_eq!(second_element.sublist().next().unwrap().value, &(6..8));
assert_none!(sublist.next());
}
#[test]
fn remove_from_empty() {
let mut nclist = NestedContainmentList::<Range<usize>, usize>::new();
assert!(!nclist.remove(&(1..5)));
}
#[test]
fn remove() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5]);
assert!(nclist.remove(&(1..5)));
}
#[test]
fn remove_not_found() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5, 6..7]);
assert!(!nclist.remove(&(1..4)));
}
#[test]
fn remove_contained() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5, 2..4]);
assert!(nclist.remove(&(2..4)));
let mut sublist = nclist.overlapping(&(..));
let first_element = sublist.next().unwrap();
assert_eq!(first_element.value, &(1..5));
assert_none!(first_element.sublist().next());
assert_none!(sublist.next());
}
#[test]
fn remove_containing() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5, 0..6]);
assert!(nclist.remove(&(0..6)));
let mut sublist = nclist.overlapping(&(..));
let first_element = sublist.next().unwrap();
assert_eq!(first_element.value, &(1..5));
assert_none!(first_element.sublist().next());
assert_none!(sublist.next());
}
#[test]
fn remove_contained_and_containing() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5, 2..4, 3..4]);
assert!(nclist.remove(&(2..4)));
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
assert_eq!(first_sublist_element_sublist.next().unwrap().value, &(3..4));
assert_none!(first_sublist_element_sublist.next());
assert_none!(sublist.next());
}
#[test]
fn remove_from_second_sublist() {
let mut nclist = NestedContainmentList::from_iter(vec![1..5, 2..4, 6..7]);
assert!(nclist.remove(&(6..7)));
}
#[test]
fn overlapping() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 3..4, 2..4, 6..7]);
let query = 4..7;
let mut overlapping = nclist.overlapping(&query);
let first_element = overlapping.next().unwrap();
assert_eq!(first_element.value, &(1..5));
assert_none!(first_element.sublist().next());
let second_element = overlapping.next().unwrap();
assert_eq!(second_element.value, &(6..7));
assert_none!(second_element.sublist().next());
assert_none!(overlapping.next());
}
#[test]
fn overlapping_skip_first() {
let nclist = NestedContainmentList::from_iter(vec![1..2, 3..4]);
let query = 3..4;
let mut overlapping = nclist.overlapping(&query);
let first_element = overlapping.next().unwrap();
assert_eq!(first_element.value, &(3..4));
assert_none!(first_element.sublist().next());
assert_none!(overlapping.next());
}
#[test]
fn overlapping_contained() {
let nclist = NestedContainmentList::from_iter(vec![1..5]);
let query = 2..3;
let mut overlapping = nclist.overlapping(&query);
let first_element = overlapping.next().unwrap();
assert_eq!(first_element.value, &(1..5));
assert_none!(first_element.sublist().next());
assert_none!(overlapping.next());
}
#[test]
fn overlapping_starts_at_topmost_element() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..3]);
let query = 2..4;
let mut overlapping = nclist.overlapping(&query);
let overlapping_element = overlapping.next().unwrap();
assert_eq!(overlapping_element.value, &(1..4));
let inner_overlapping_element = overlapping_element.sublist().next().unwrap();
assert_eq!(inner_overlapping_element.value, &(2..3));
}
#[test]
fn overlapping_stops_early() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..5]);
let query = 1..2;
let mut overlapping = nclist.overlapping(&query);
assert_eq!(overlapping.next().unwrap().value, &(1..4));
assert_none!(overlapping.next());
}
#[test]
fn overlapping_with_inner_not_overlapping() {
let nclist = NestedContainmentList::from(vec![1..5, 1..2, 2..3, 4..5, 0..0]);
let mut overlapping = nclist.overlapping(&(2..3));
let element = overlapping.next().unwrap();
assert_eq!(element.value, &(1..5));
assert_eq!(element.sublist().next().unwrap().value, &(2..3));
}
#[test]
fn overlapping_last() {
let nclist = NestedContainmentList::from_iter(vec![1..2, 2..5, 3..4, 6..7]);
let last = nclist.overlapping(&(1..4)).last().unwrap();
assert_eq!(last.value, &(2..5));
assert_eq!(last.sublist().next().unwrap().value, &(3..4));
}
#[test]
fn overlapping_size_hint() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..3, 4..7]);
let query = 1..3;
let overlapping = nclist.overlapping(&query);
assert_eq!(overlapping.size_hint(), (1, Some(3)));
}
#[test]
fn overlapping_size_hint_empty() {
let nclist = NestedContainmentList::<Range<usize>, usize>::new();
let query = 1..3;
let overlapping = nclist.overlapping(&query);
assert_eq!(overlapping.size_hint(), (0, Some(0)));
}
#[test]
fn overlapping_size_hint_after_iterating() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..3, 4..7]);
let query = 1..5;
let mut overlapping = nclist.overlapping(&query);
overlapping.next();
assert_eq!(overlapping.size_hint(), (1, Some(1)));
}
#[test]
fn overlapping_element_into_iter() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..3]);
let mut overlapping = nclist.overlapping(&(2..5));
let first_element = overlapping.next().unwrap();
let mut first_element_iter = first_element.into_iter();
assert_eq!(first_element_iter.next().unwrap().value, &(1..4));
assert_eq!(first_element_iter.next().unwrap().value, &(2..3));
}
#[test]
fn overlapping_next_back() {
let nclist = NestedContainmentList::from_iter(vec![0..1, 1..2, 2..5, 2..4, 6..7]);
let mut overlapping = nclist.overlapping(&(1..4));
let second_element = overlapping.next_back().unwrap();
assert_eq!(second_element.value, &(2..5));
let mut second_element_sublist = second_element.sublist();
assert_eq!(second_element_sublist.next_back().unwrap().value, &(2..4));
assert_none!(second_element_sublist.next_back());
let first_element = overlapping.next_back().unwrap();
assert_eq!(first_element.value, &(1..2));
assert_none!(first_element.sublist().next_back());
assert_none!(overlapping.next_back());
}
#[test]
fn from_iter() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 3..4, 2..4, 6..7]);
let mut sublist = nclist.overlapping(&(..));
let first_sublist_element = sublist.next().unwrap();
assert_eq!(first_sublist_element.value, &(1..5));
let mut first_sublist_element_sublist = first_sublist_element.sublist();
let second_sublist_element = first_sublist_element_sublist.next().unwrap();
assert_eq!(second_sublist_element.value, &(2..4));
let mut second_sublist_element_sublist = second_sublist_element.sublist();
assert_eq!(
second_sublist_element_sublist.next().unwrap().value,
&(3..4)
);
assert_none!(first_sublist_element_sublist.next());
assert_eq!(sublist.next().unwrap().value, &(6..7));
assert_none!(sublist.next());
}
#[test]
fn into_iter() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 3..4, 2..4, 6..7]);
let mut iter = nclist.into_iter();
let first_sublist_element = iter.next().unwrap();
assert_eq!(first_sublist_element.value, 1..5);
let mut first_sublist_element_sublist = first_sublist_element.sublist();
let second_sublist_element = first_sublist_element_sublist.next().unwrap();
assert_eq!(second_sublist_element.value, 2..4);
let mut second_sublist_element_sublist = second_sublist_element.sublist();
assert_eq!(second_sublist_element_sublist.next().unwrap().value, 3..4);
assert_none!(first_sublist_element_sublist.next());
assert_eq!(iter.next().unwrap().value, 6..7);
assert_none!(iter.next());
}
#[test]
fn iter_last() {
let nclist = NestedContainmentList::from_iter(vec![1..2, 2..5, 3..4]);
let last = nclist.into_iter().last().unwrap();
assert_eq!(last.value, 2..5);
assert_eq!(last.sublist().next().unwrap().value, 3..4);
}
#[test]
fn iter_size_hint() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 2..5, 6..7]);
let iter = nclist.into_iter();
assert_eq!(iter.size_hint(), (1, Some(3)));
}
#[test]
fn iter_size_hint_empty() {
let nclist = NestedContainmentList::<Range<usize>, usize>::new();
let iter = nclist.into_iter();
assert_eq!(iter.size_hint(), (0, Some(0)));
}
#[test]
fn iter_size_hint_after_iterating() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 2..5, 6..7]);
let mut iter = nclist.into_iter();
iter.next();
assert_eq!(iter.size_hint(), (1, Some(1)));
}
#[test]
fn iter_next_back() {
let nclist = NestedContainmentList::from_iter(vec![1..5, 3..4, 2..4, 6..7]);
let mut iter = nclist.into_iter();
let second_element = iter.next_back().unwrap();
assert_eq!(second_element.value, 6..7);
assert_none!(second_element.sublist().next_back());
let first_element = iter.next_back().unwrap();
assert_eq!(first_element.value, 1..5);
let mut first_element_sublist = first_element.sublist();
let second_sublist_element = first_element_sublist.next_back().unwrap();
assert_eq!(second_sublist_element.value, 2..4);
let mut second_sublist_element_sublist = second_sublist_element.sublist();
assert_eq!(
second_sublist_element_sublist.next_back().unwrap().value,
3..4
);
assert_none!(second_sublist_element_sublist.next_back());
assert_none!(first_element_sublist.next_back());
assert_none!(iter.next_back());
}
#[test]
fn iter_element_into_iter() {
let nclist = NestedContainmentList::from_iter(vec![1..4, 2..3]);
let mut iter = nclist.into_iter();
let first_element = iter.next().unwrap();
let mut first_element_iter = first_element.into_iter();
assert_eq!(first_element_iter.next().unwrap().value, 1..4);
assert_eq!(first_element_iter.next().unwrap().value, 2..3);
}
#[test]
fn extend() {
let mut nclist = NestedContainmentList::from(vec![2..3, 1..4, 7..8]);
nclist.extend(vec![0..5, 6..7, 7..9, 10..11]);
assert_eq!(
Into::<Vec<_>>::into(nclist),
vec![0..5, 1..4, 2..3, 6..7, 7..9, 7..8, 10..11]
);
}
#[test]
fn from_vec() {
let nclist = NestedContainmentList::from(vec![2..3, 1..4, 5..6]);
assert_eq!(Into::<Vec<_>>::into(nclist), vec![1..4, 2..3, 5..6]);
}
#[test]
fn from_slice() {
let slice = &[2..3, 1..4, 5..6][..];
let nclist = NestedContainmentList::from(slice);
let mut iter = nclist.into_iter();
let first_element = iter.next().unwrap();
assert_eq!(first_element.value, 1..4);
assert_eq!(first_element.sublist().next().unwrap().value, 2..3);
let second_element = iter.next().unwrap();
assert_eq!(second_element.value, 5..6);
}
#[test]
fn into_vec() {
let vec: Vec<_> = NestedContainmentList::from_iter(vec![2..3, 1..4, 5..6]).into();
let nclist: NestedContainmentList<_, _> = vec.into();
let mut iter = nclist.into_iter();
let first_element = iter.next().unwrap();
assert_eq!(first_element.value, 1..4);
assert_eq!(first_element.sublist().next().unwrap().value, 2..3);
let second_element = iter.next().unwrap();
assert_eq!(second_element.value, 5..6);
}
}