#![doc(html_root_url = "https://docs.rs/rotated-array-set/0.1.0/rotated_array_set/")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/senderista/rotated-array-set/master/img/cells.png"
)]
use std::cmp::Ordering::{self, Equal, Greater, Less};
use std::cmp::{max, min};
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FromIterator, FusedIterator, Peekable};
use std::mem;
use std::ops::Bound::{Excluded, Included, Unbounded};
use std::ops::RangeBounds;
use is_sorted::IsSorted;
#[derive(Debug, Clone)]
pub struct RotatedArraySet<T> {
data: Vec<T>,
min_indexes: Vec<usize>,
min_data: Vec<T>,
}
#[derive(Debug, Copy, Clone)]
struct Range<'a, T: 'a> {
container: &'a RotatedArraySet<T>,
start_index_inclusive: usize,
end_index_exclusive: usize,
}
impl<'a, T> Range<'a, T>
where
T: Ord + Copy + Default + Debug,
{
fn with_bounds(
container: &'a RotatedArraySet<T>,
start_index_inclusive: usize,
end_index_exclusive: usize,
) -> Range<'a, T> {
assert!(end_index_exclusive >= start_index_inclusive);
assert!(end_index_exclusive <= container.len());
Range {
container,
start_index_inclusive,
end_index_exclusive,
}
}
fn new(container: &'a RotatedArraySet<T>) -> Range<'a, T> {
Range::with_bounds(container, 0, container.len())
}
fn at(&self, index: usize) -> Option<&'a T> {
let container_idx = index + self.start_index_inclusive;
self.container.select(container_idx)
}
fn len(&self) -> usize {
self.end_index_exclusive - self.start_index_inclusive
}
}
#[derive(Debug, Copy, Clone)]
pub struct Iter<'a, T: 'a> {
range: Range<'a, T>,
next_index: usize,
next_rev_index: usize,
}
impl<'a, T> Iter<'a, T>
where
T: Ord + Copy + Default + Debug,
{
fn new(range: Range<'a, T>) -> Iter<'a, T> {
let next_index = 0;
let next_rev_index = if range.len() == 0 { 0 } else { range.len() - 1 };
Iter {
range,
next_index,
next_rev_index,
}
}
#[inline(always)]
fn assert_invariants(&self) -> bool {
assert!(self.next_index <= self.range.len());
assert!(self.next_rev_index <= self.range.len());
if self.next_rev_index < self.next_index {
assert!(self.next_index - self.next_rev_index == 1);
}
true
}
}
#[derive(Debug, Clone)]
pub struct IntoIter<T> {
vec: Vec<T>,
next_index: usize,
}
#[derive(Debug, Clone)]
pub struct Difference<'a, T: 'a> {
self_iter: Iter<'a, T>,
other_set: &'a RotatedArraySet<T>,
}
#[derive(Debug, Clone)]
pub struct SymmetricDifference<'a, T: 'a>
where
T: Ord + Copy + Default + Debug,
{
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
}
#[derive(Debug, Clone)]
pub struct Intersection<'a, T: 'a> {
small_iter: Iter<'a, T>,
large_set: &'a RotatedArraySet<T>,
}
#[derive(Debug, Clone)]
pub struct Union<'a, T: 'a>
where
T: Ord + Copy + Default + Debug,
{
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
}
impl<T> RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
pub fn new() -> Self {
RotatedArraySet {
data: Vec::new(),
min_indexes: Vec::new(),
min_data: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> RotatedArraySet<T> {
let min_indexes_capacity = if capacity > 0 {
Self::get_subarray_idx_from_array_idx(capacity - 1) + 1
} else {
0
};
RotatedArraySet {
data: Vec::with_capacity(capacity),
min_indexes: Vec::with_capacity(min_indexes_capacity),
min_data: Vec::with_capacity(min_indexes_capacity),
}
}
pub fn clear(&mut self) {
self.data.clear();
self.min_indexes.clear();
self.min_data.clear();
}
pub fn contains(&self, value: &T) -> bool {
self.get(value).is_some()
}
pub fn is_disjoint(&self, other: &RotatedArraySet<T>) -> bool {
self.intersection(other).next().is_none()
}
pub fn is_subset(&self, other: &RotatedArraySet<T>) -> bool {
if self.len() > other.len() {
false
} else {
for next in self {
if !other.contains(next) {
return false;
}
}
true
}
}
pub fn is_superset(&self, other: &RotatedArraySet<T>) -> bool {
other.is_subset(self)
}
pub fn get(&self, value: &T) -> Option<&T> {
let raw_idx = self.find_raw_index(value).ok()?;
Some(&self.data[raw_idx])
}
pub fn rank(&self, value: &T) -> Result<usize, usize> {
let (raw_index, exists) = match self.find_raw_index(value) {
Ok(index) => (index, true),
Err(index) => (index, false),
};
if raw_index == self.data.len() {
return Err(raw_index);
}
debug_assert!(raw_index < self.data.len());
let subarray_idx = Self::get_subarray_idx_from_array_idx(raw_index);
let subarray_start_idx = Self::get_array_idx_from_subarray_idx(subarray_idx);
let subarray_len = if subarray_idx == self.min_indexes.len() - 1 {
self.data.len() - subarray_start_idx
} else {
subarray_idx + 1
};
let pivot_idx = subarray_start_idx + self.min_indexes[subarray_idx];
let logical_index = if raw_index >= pivot_idx {
subarray_start_idx + raw_index - pivot_idx
} else {
subarray_start_idx + subarray_len - (pivot_idx - raw_index)
};
if exists {
Ok(logical_index)
} else {
Err(logical_index)
}
}
pub fn select(&self, rank: usize) -> Option<&T> {
if rank >= self.data.len() {
return None;
}
let subarray_idx = Self::get_subarray_idx_from_array_idx(rank);
let subarray_start_idx = Self::get_array_idx_from_subarray_idx(subarray_idx);
let subarray_len = if subarray_idx == self.min_indexes.len() - 1 {
self.data.len() - subarray_start_idx
} else {
subarray_idx + 1
};
debug_assert!(rank >= subarray_start_idx);
let idx_offset = rank - subarray_start_idx;
let pivot_offset = self.min_indexes[subarray_idx];
let rotated_offset = (pivot_offset + idx_offset) % subarray_len;
debug_assert!(rotated_offset < subarray_len);
let raw_idx = subarray_start_idx + rotated_offset;
Some(&self.data[raw_idx])
}
pub fn insert(&mut self, value: T) -> bool {
let insert_idx = match self.find_raw_index(&value).err() {
None => return false,
Some(idx) => idx,
};
let subarray_idx = Self::get_subarray_idx_from_array_idx(insert_idx);
debug_assert!(subarray_idx <= self.min_indexes.len());
if subarray_idx == self.min_indexes.len() {
self.min_indexes.push(0);
self.min_data.push(T::default());
}
debug_assert_eq!(self.min_indexes.len(), self.min_data.len());
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
if subarray_idx == self.min_indexes.len() - 1 && !self.is_last_subarray_full() {
debug_assert!(self.min_indexes[subarray_idx] == 0);
self.data.insert(insert_idx, value);
self.min_data[subarray_idx] = self.data[subarray_offset];
debug_assert!(self.assert_invariants());
return true;
}
let next_subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx + 1);
let subarray = &mut self.data[subarray_offset..next_subarray_offset];
let pivot_offset = self.min_indexes[subarray_idx];
let insert_offset = insert_idx - subarray_offset;
let max_offset = if pivot_offset == 0 {
subarray.len() - 1
} else {
pivot_offset - 1
};
let mut prev_max = subarray[max_offset];
if max_offset < pivot_offset && insert_offset >= pivot_offset {
subarray.copy_within(pivot_offset..insert_offset, max_offset);
subarray[insert_offset - 1] = value;
self.min_indexes[subarray_idx] = max_offset;
self.min_data[subarray_idx] = subarray[max_offset];
} else {
subarray.copy_within(insert_offset..max_offset, insert_offset + 1);
subarray[insert_offset] = value;
if insert_offset == pivot_offset {
self.min_data[subarray_idx] = value;
}
}
debug_assert!(self.assert_invariants());
let max_subarray_idx = self.min_indexes.len() - 1;
let next_subarray_idx = subarray_idx + 1;
let last_subarray_full = self.is_last_subarray_full();
for (i, pivot_offset_ref) in self.min_indexes[next_subarray_idx..].iter_mut().enumerate() {
let cur_subarray_idx = next_subarray_idx + i;
if cur_subarray_idx == max_subarray_idx && !last_subarray_full {
break;
}
let max_offset = if *pivot_offset_ref == 0 {
cur_subarray_idx
} else {
*pivot_offset_ref - 1
};
let max_idx = max_offset + Self::get_array_idx_from_subarray_idx(cur_subarray_idx);
let next_max = self.data[max_idx];
self.data[max_idx] = prev_max;
*pivot_offset_ref = max_offset;
self.min_data[cur_subarray_idx] = prev_max;
prev_max = next_max;
}
if last_subarray_full {
self.data.push(prev_max);
self.min_indexes.push(0);
self.min_data.push(prev_max);
} else {
let max_subarray_offset = Self::get_array_idx_from_subarray_idx(max_subarray_idx);
debug_assert!(prev_max <= self.data[max_subarray_offset]);
self.data.insert(max_subarray_offset, prev_max);
self.min_data[max_subarray_idx] = prev_max;
}
debug_assert!(self.find_raw_index(&value).is_ok());
debug_assert!(self.assert_invariants());
true
}
pub fn remove(&mut self, value: &T) -> bool {
let mut remove_idx = match self.find_raw_index(&value).ok() {
Some(idx) => idx,
None => return false,
};
let max_subarray_idx = self.min_indexes.len() - 1;
let max_subarray_offset = Self::get_array_idx_from_subarray_idx(max_subarray_idx);
let subarray_idx = Self::get_subarray_idx_from_array_idx(remove_idx);
debug_assert!(subarray_idx <= max_subarray_idx);
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
let mut max_subarray_remove_idx = if subarray_idx == max_subarray_idx {
remove_idx
} else {
max_subarray_offset
};
if self.is_last_subarray_full() {
let last_min_offset = self.min_indexes[max_subarray_idx];
self.data[max_subarray_offset..].rotate_left(last_min_offset);
self.min_indexes[max_subarray_idx] = 0;
if subarray_idx == max_subarray_idx {
remove_idx = self
.find_raw_index(&value)
.expect("recalculating remove index after sorting");
max_subarray_remove_idx = remove_idx;
}
}
if subarray_idx < max_subarray_idx {
let next_subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx + 1);
let subarray = &mut self.data[subarray_offset..next_subarray_offset];
let pivot_offset = self.min_indexes[subarray_idx];
let remove_offset = remove_idx - subarray_offset;
let max_offset = if pivot_offset == 0 {
subarray.len() - 1
} else {
pivot_offset - 1
};
let mut prev_max_offset = if max_offset < pivot_offset && remove_offset >= pivot_offset
{
subarray.copy_within(pivot_offset..remove_offset, pivot_offset + 1);
let new_pivot_offset = if pivot_offset == subarray.len() - 1 {
0
} else {
pivot_offset + 1
};
self.min_indexes[subarray_idx] = new_pivot_offset;
self.min_data[subarray_idx] = subarray[new_pivot_offset];
pivot_offset
} else {
subarray.copy_within(remove_offset + 1..=max_offset, remove_offset);
if remove_offset == pivot_offset {
self.min_data[subarray_idx] = subarray[pivot_offset];
}
max_offset
};
let next_subarray_idx = min(max_subarray_idx, subarray_idx + 1);
for (i, pivot_offset_ref) in self.min_indexes[next_subarray_idx..max_subarray_idx]
.iter_mut()
.enumerate()
{
let cur_subarray_idx = next_subarray_idx + i;
let cur_subarray_offset = Self::get_array_idx_from_subarray_idx(cur_subarray_idx);
let prev_max_idx =
prev_max_offset + Self::get_array_idx_from_subarray_idx(cur_subarray_idx - 1);
self.data[prev_max_idx] = self.data[cur_subarray_offset + *pivot_offset_ref];
if cur_subarray_idx == 1 {
self.min_data[0] = self.data[0];
debug_assert!(IsSorted::is_sorted(&mut self.min_data.iter()));
}
prev_max_offset = *pivot_offset_ref;
let new_min_offset = if *pivot_offset_ref == cur_subarray_idx {
0
} else {
*pivot_offset_ref + 1
};
*pivot_offset_ref = new_min_offset;
self.min_data[cur_subarray_idx] = self.data[cur_subarray_offset + new_min_offset];
debug_assert!(IsSorted::is_sorted(&mut self.min_data.iter()));
}
let prev_max_idx =
prev_max_offset + Self::get_array_idx_from_subarray_idx(max_subarray_idx - 1);
self.data[prev_max_idx] = self.data[max_subarray_offset];
if max_subarray_idx == 1 {
self.min_data[0] = self.data[0];
debug_assert!(IsSorted::is_sorted(&mut self.min_data.iter()));
}
}
self.data.remove(max_subarray_remove_idx);
if max_subarray_offset == self.data.len() {
self.min_indexes.pop();
self.min_data.pop();
} else {
self.min_data[max_subarray_idx] = self.data[max_subarray_offset];
debug_assert!(IsSorted::is_sorted(&mut self.min_data.iter()));
}
debug_assert!(self.find_raw_index(&value).is_err());
debug_assert!(self.assert_invariants());
true
}
pub fn take(&mut self, value: &T) -> Option<T> {
let ret = self.get(value).copied();
if ret.is_some() {
self.remove(value);
}
ret
}
pub fn append(&mut self, other: &mut Self) {
let mut union: Self = self.union(other).cloned().collect();
other.clear();
mem::swap(self, &mut union);
}
pub fn split_off(&mut self, value: &T) -> Self {
let tail = self.range((Included(value), Unbounded));
if tail.len() == 0 {
Self::default()
} else if tail.len() == self.len() {
mem::replace(self, Self::default())
} else {
let new_len = self.len() - tail.len();
let tail_set: Self = tail.cloned().collect();
self.truncate(new_len);
tail_set
}
}
pub fn truncate(&mut self, len: usize) {
if len == 0 {
self.clear();
} else if len < self.len() {
let index = len - 1;
let subarray_idx = Self::get_subarray_idx_from_array_idx(index);
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
let next_subarray_offset = if subarray_idx == self.min_indexes.len() - 1 {
self.data.len()
} else {
Self::get_array_idx_from_subarray_idx(subarray_idx + 1)
};
let subarray = &mut self.data[subarray_offset..next_subarray_offset];
let min_offset = self.min_indexes[subarray_idx];
subarray.rotate_left(min_offset);
self.min_indexes[subarray_idx] = 0;
self.data.truncate(len);
self.min_indexes.truncate(subarray_idx + 1);
self.min_data.truncate(subarray_idx + 1);
}
debug_assert!(self.assert_invariants());
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(Range::new(self))
}
pub fn range<R>(&self, range: R) -> Iter<'_, T>
where
R: RangeBounds<T>,
{
let range = self.get_range(range);
Iter::new(range)
}
fn get_range<R>(&self, range: R) -> Range<'_, T>
where
R: RangeBounds<T>,
{
match (range.start_bound(), range.end_bound()) {
(Excluded(s), Excluded(e)) if s == e => {
panic!("range start and end are equal and excluded in RotatedArraySet")
}
(Included(s), Included(e))
| (Included(s), Excluded(e))
| (Excluded(s), Included(e))
| (Excluded(s), Excluded(e))
if s > e =>
{
panic!("range start is greater than range end in RotatedArraySet")
}
_ => {}
};
let start_index_inclusive = match range.start_bound() {
Unbounded => 0,
Included(s) => match self.find_raw_index(s) {
Ok(index) => index,
Err(index) => index,
},
Excluded(s) => match self.find_raw_index(s) {
Ok(index) => index + 1,
Err(index) => index,
},
};
let end_index_exclusive = match range.end_bound() {
Unbounded => self.len(),
Included(e) => match self.find_raw_index(e) {
Ok(index) => index + 1,
Err(index) => index,
},
Excluded(e) => match self.find_raw_index(e) {
Ok(index) => index,
Err(index) => index,
},
};
Range::with_bounds(self, start_index_inclusive, end_index_exclusive)
}
pub fn difference<'a>(&'a self, other: &'a RotatedArraySet<T>) -> Difference<'a, T> {
Difference {
self_iter: self.iter(),
other_set: other,
}
}
pub fn symmetric_difference<'a>(
&'a self,
other: &'a RotatedArraySet<T>,
) -> SymmetricDifference<'a, T> {
SymmetricDifference {
a: self.iter().peekable(),
b: other.iter().peekable(),
}
}
pub fn intersection<'a>(&'a self, other: &'a RotatedArraySet<T>) -> Intersection<'a, T> {
let (small, other) = if self.len() <= other.len() {
(self, other)
} else {
(other, self)
};
Intersection {
small_iter: small.iter(),
large_set: other,
}
}
pub fn union<'a>(&'a self, other: &'a RotatedArraySet<T>) -> Union<'a, T> {
Union {
a: self.iter().peekable(),
b: other.iter().peekable(),
}
}
fn integer_sum(n: usize) -> usize {
(n * (n + 1)) / 2
}
fn integer_sum_inverse(n: usize) -> usize {
((f64::from((n * 8 + 1) as u32).sqrt() as usize) - 1) / 2
}
fn get_subarray_idx_from_array_idx(idx: usize) -> usize {
if idx == 0 {
0
} else {
Self::integer_sum_inverse(idx)
}
}
fn get_array_idx_from_subarray_idx(idx: usize) -> usize {
if idx == 0 {
0
} else {
Self::integer_sum(idx)
}
}
fn is_last_subarray_full(&self) -> bool {
self.data.len() == Self::get_array_idx_from_subarray_idx(self.min_indexes.len())
}
fn find_raw_index(&self, value: &T) -> Result<usize, usize> {
if self.data.is_empty() {
return Err(0);
}
debug_assert!(self.assert_invariants());
match self.min_data.binary_search(value) {
Ok(idx) => {
let found_idx = Self::get_array_idx_from_subarray_idx(idx) + self.min_indexes[idx];
debug_assert!(found_idx < self.len());
Ok(found_idx)
}
Err(idx) => {
let subarray_idx = if idx == 0 {
0
} else if idx == self.min_indexes.len() && !self.is_last_subarray_full() {
idx - 1
} else {
let prev_max_idx = if self.min_indexes[idx - 1] == 0 {
Self::get_array_idx_from_subarray_idx(idx) - 1
} else {
Self::get_array_idx_from_subarray_idx(idx - 1) + self.min_indexes[idx - 1]
- 1
};
if *value <= self.data[prev_max_idx] {
idx - 1
} else {
idx
}
};
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
debug_assert!(subarray_offset <= self.data.len());
if subarray_offset == self.data.len() {
return Err(subarray_offset);
}
let next_subarray_offset = if subarray_idx == self.min_indexes.len() - 1 {
self.data.len()
} else {
Self::get_array_idx_from_subarray_idx(subarray_idx + 1)
};
let subarray = &self.data[subarray_offset..next_subarray_offset];
let pivot_offset = self.min_indexes[subarray_idx];
let subarray_pivot = subarray_offset + pivot_offset;
let (left, right) = subarray.split_at(pivot_offset);
debug_assert!(
IsSorted::is_sorted(&mut left.iter()) && IsSorted::is_sorted(&mut right.iter())
);
match (left.binary_search(value), right.binary_search(value)) {
(Ok(idx), _) => Ok(subarray_offset + idx),
(_, Ok(idx)) => Ok(subarray_pivot + idx),
(Err(left_idx), Err(right_idx))
if right_idx == right.len() && !left.is_empty() =>
{
Err(subarray_offset + left_idx)
}
(Err(_left_idx), Err(right_idx))
if right_idx < right.len() || left.is_empty() =>
{
Err(subarray_pivot + right_idx)
}
(Err(_), Err(_)) => unreachable!(),
}
}
}
}
#[inline(always)]
fn assert_invariants(&self) -> bool {
assert!(IsSorted::is_sorted(&mut self.min_data.iter()));
let mut min_data_dedup = self.min_data.clone();
min_data_dedup.dedup();
assert!(self.min_data[..] == min_data_dedup[..]);
assert!(self
.min_indexes
.iter()
.enumerate()
.all(|(idx, &offset)| offset <= idx));
assert!(self
.min_indexes
.iter()
.enumerate()
.all(|(idx, &offset)| self.min_data[idx]
== self.data[Self::get_array_idx_from_subarray_idx(idx) + offset]));
for i in 0..self.min_indexes.len() {
let subarray_begin_idx = Self::get_array_idx_from_subarray_idx(i);
let subarray_end_idx = min(
self.data.len(),
Self::get_array_idx_from_subarray_idx(i + 1),
);
let subarray = &self.data[subarray_begin_idx..subarray_end_idx];
let min_idx = subarray
.iter()
.enumerate()
.min_by(|&(_, v1), &(_, v2)| v1.cmp(v2))
.unwrap()
.0;
assert!(min_idx == self.min_indexes[i]);
}
true
}
fn init(&mut self) {
debug_assert!(self.min_indexes.is_empty() && self.min_data.is_empty());
if !self.data.is_empty() {
self.data.sort_unstable(); let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.data.len() - 1);
self.min_indexes = vec![0; last_subarray_idx + 1];
for subarray_idx in 0..=last_subarray_idx {
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
self.min_data.push(self.data[subarray_offset]);
}
}
}
}
impl<T> PartialEq for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for i in 0..self.len() {
if self.select(i).unwrap() != other.select(i).unwrap() {
return false;
}
}
true
}
}
impl<T> Eq for RotatedArraySet<T> where T: Ord + Copy + Default + Debug {}
impl<T> Hash for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug + Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
for i in 0..self.len() {
self.select(i).hash(state);
}
}
}
impl<'a, T> Iterator for Iter<'a, T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.len() == 0 || self.next_index > self.next_rev_index {
None
} else {
let current = self.range.at(self.next_index);
self.next_index += 1;
debug_assert!(self.assert_invariants());
current
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.next_index = min(self.next_index + n, self.len());
let ret = if self.len() == 0 || self.next_index > self.next_rev_index {
None
} else {
let nth = self.range.at(self.next_index);
self.next_index += 1;
nth
};
debug_assert!(self.assert_invariants());
ret
}
fn count(self) -> usize {
self.len() - self.next_index
}
fn last(self) -> Option<Self::Item> {
if self.len() == 0 {
None
} else {
self.range.at(self.len() - 1)
}
}
fn max(self) -> Option<Self::Item> {
if self.len() == 0 {
None
} else {
self.range.at(self.len() - 1)
}
}
fn min(self) -> Option<Self::Item> {
self.range.at(0)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining_count = self.len() - self.next_index;
(remaining_count, Some(remaining_count))
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T>
where
T: Ord + Copy + Default + Debug,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.len() == 0 || self.next_rev_index < self.next_index {
None
} else {
let current = self.range.at(self.next_rev_index);
if self.next_rev_index == 0 {
self.next_index += 1;
} else {
self.next_rev_index -= 1;
}
debug_assert!(self.assert_invariants());
current
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.next_rev_index = self.next_rev_index.saturating_sub(n);
let ret = if self.len() == 0 || self.next_rev_index < self.next_index {
None
} else {
let nth = self.range.at(self.next_rev_index);
if self.next_rev_index == 0 {
self.next_index += 1;
} else {
self.next_rev_index -= 1;
}
nth
};
debug_assert!(self.assert_invariants());
ret
}
}
impl<T> ExactSizeIterator for Iter<'_, T>
where
T: Ord + Copy + Default + Debug,
{
fn len(&self) -> usize {
self.range.len()
}
}
impl<T> FusedIterator for Iter<'_, T> where T: Ord + Copy + Default + Debug {}
impl<'a, T> IntoIterator for &'a RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> IntoIterator for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
vec: self.into(),
next_index: 0,
}
}
}
impl<'a, T> Iterator for IntoIter<T>
where
T: Ord + Copy + Default + Debug,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.next_index == self.vec.len() {
None
} else {
let current = self.vec[self.next_index];
self.next_index += 1;
debug_assert!(self.next_index <= self.vec.len());
Some(current)
}
}
}
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
(None, _) => short,
(_, None) => long,
(Some(x1), Some(y1)) => x1.cmp(y1),
}
}
impl<'a, T> Iterator for Difference<'a, T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let self_next = self.self_iter.next()?;
if !self.other_set.contains(&self_next) {
return Some(self_next);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (self_len, other_len) = (self.self_iter.len(), self.other_set.len());
(self_len.saturating_sub(other_len), Some(self_len))
}
}
impl<T> FusedIterator for Difference<'_, T> where T: Ord + Copy + Default + Debug {}
impl<'a, T> Iterator for SymmetricDifference<'a, T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => return self.a.next(),
Equal => {
self.a.next();
self.b.next();
}
Greater => return self.b.next(),
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.a.len() + self.b.len()))
}
}
impl<T> FusedIterator for SymmetricDifference<'_, T> where T: Ord + Copy + Default + Debug {}
impl<'a, T> Iterator for Intersection<'a, T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let small_next = self.small_iter.next()?;
if self.large_set.contains(&small_next) {
return Some(small_next);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let min_len = self.small_iter.len();
(0, Some(min_len))
}
}
impl<T> FusedIterator for Intersection<'_, T> where T: Ord + Copy + Default + Debug {}
impl<'a, T> Iterator for Union<'a, T>
where
T: Ord + Copy + Default + Debug,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => self.a.next(),
Equal => {
self.b.next();
self.a.next()
}
Greater => self.b.next(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let a_len = self.a.len();
let b_len = self.b.len();
(max(a_len, b_len), Some(a_len + b_len))
}
}
impl<T> FusedIterator for Union<'_, T> where T: Ord + Copy + Default + Debug {}
impl<'a, T> From<&'a [T]> for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn from(slice: &[T]) -> Self {
let mut this = RotatedArraySet {
data: slice.to_vec(),
min_indexes: Vec::new(),
min_data: Vec::new(),
};
this.init();
this
}
}
impl<T> From<Vec<T>> for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn from(vec: Vec<T>) -> Self {
let mut this = RotatedArraySet {
data: vec,
min_indexes: Vec::new(),
min_data: Vec::new(),
};
this.init();
this
}
}
impl<T> Into<Vec<T>> for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn into(mut self) -> Vec<T> {
for (i, &pivot_offset) in self.min_indexes.iter().enumerate() {
let subarray_start_idx = Self::get_array_idx_from_subarray_idx(i);
let subarray_len = if i == self.min_indexes.len() - 1 {
self.data.len() - subarray_start_idx
} else {
i + 1
};
let subarray_end_idx = subarray_start_idx + subarray_len;
let subarray = &mut self.data[subarray_start_idx..subarray_end_idx];
subarray.rotate_left(pivot_offset);
}
self.data
}
}
impl<T> FromIterator<T> for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut this = RotatedArraySet {
data: Vec::from_iter(iter.into_iter()),
min_indexes: Vec::new(),
min_data: Vec::new(),
};
this.init();
this
}
}
impl<T> Default for RotatedArraySet<T>
where
T: Ord + Copy + Default + Debug,
{
fn default() -> RotatedArraySet<T> {
RotatedArraySet::new()
}
}