#![doc(html_root_url = "https://docs.rs/rotated-vec/0.1.0/rotated_vec/")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/senderista/rotated-array-set/master/img/cells.png")]
use std::mem;
use std::cmp::{min, Ordering};
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FromIterator, FusedIterator};
use std::ops::{Index, IndexMut};
#[derive(Debug, Clone)]
pub struct RotatedVec<T> {
data: Vec<T>,
start_indexes: Vec<usize>,
}
#[derive(Debug, Copy, Clone)]
pub struct Iter<'a, T: 'a> {
container: &'a RotatedVec<T>,
next_index: usize,
next_rev_index: usize,
}
impl<'a, T> Iter<'a, T>
where
T: Copy + Default + Debug,
{
#[inline(always)]
fn assert_invariants(&self) -> bool {
assert!(self.next_index <= self.container.len());
assert!(self.next_rev_index <= self.container.len());
if self.next_rev_index < self.next_index {
assert!(self.next_index - self.next_rev_index == 1);
}
true
}
}
#[derive(Debug)]
pub struct IterMut<'a, T: 'a> {
container: &'a mut RotatedVec<T>,
next_index: usize,
next_rev_index: usize,
}
impl<'a, T> IterMut<'a, T>
where
T: Copy + Default + Debug,
{
#[inline(always)]
fn assert_invariants(&self) -> bool {
assert!(self.next_index <= self.container.len());
assert!(self.next_rev_index <= self.container.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,
}
impl<T> RotatedVec<T>
where
T: Copy + Default + Debug,
{
pub fn new() -> Self {
RotatedVec {
data: Vec::new(),
start_indexes: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> RotatedVec<T> {
let start_indexes_capacity = if capacity > 0 {
Self::get_subarray_idx_from_array_idx(capacity - 1) + 1
} else {
0
};
RotatedVec {
data: Vec::with_capacity(capacity),
start_indexes: Vec::with_capacity(start_indexes_capacity),
}
}
pub fn get(&self, index: usize) -> Option<&T> {
if index >= self.data.len() {
return None;
}
let real_idx = self.get_real_index(index);
Some(&self.data[real_idx])
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index >= self.data.len() {
return None;
}
let real_idx = self.get_real_index(index);
Some(&mut self.data[real_idx])
}
pub fn swap(&mut self, a: usize, b: usize) {
self.data.swap(a, b);
}
pub fn capacity(&self) -> usize {
self.data.capacity()
}
pub fn reserve_exact(&mut self, additional: usize) {
self.data.reserve_exact(additional);
}
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
}
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
pub fn truncate(&mut self, len: usize) {
if len >= self.len() {
return
}
self.unrotate_last_subarray();
let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.len() - 1);
self.start_indexes.truncate(last_subarray_idx + 1);
self.data.truncate(len);
}
pub fn iter(&self) -> Iter<T> {
Iter {
container: self,
next_index: 0,
next_rev_index: if self.len() == 0 { 0 } else { self.len() - 1 },
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
let len = self.len();
IterMut {
container: self,
next_index: 0,
next_rev_index: len - 1,
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
self.start_indexes.clear();
}
pub fn contains(&self, x: &T) -> bool
where T: PartialEq<T>
{
self.data.contains(x)
}
pub fn push(&mut self, value: T) {
self.insert(self.len(), value);
}
pub fn pop(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
Some(self.remove(self.len() - 1))
}
}
pub fn insert(&mut self, index: usize, element: T) {
assert!(index <= self.len());
let insert_idx = if index < self.len() {
self.get_real_index(index)
} else {
self.len()
};
let subarray_idx = Self::get_subarray_idx_from_array_idx(insert_idx);
debug_assert!(subarray_idx <= self.start_indexes.len());
if subarray_idx == self.start_indexes.len() {
self.start_indexes.push(0);
}
let subarray_offset = Self::get_array_idx_from_subarray_idx(subarray_idx);
if subarray_idx == self.start_indexes.len() - 1 && !self.is_last_subarray_full() {
debug_assert!(self.start_indexes[subarray_idx] == 0);
self.data.insert(insert_idx, element);
debug_assert!(self.assert_invariants());
return;
}
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.start_indexes[subarray_idx];
let insert_offset = insert_idx - subarray_offset;
let end_offset = if pivot_offset == 0 {
subarray.len() - 1
} else {
pivot_offset - 1
};
let mut prev_end_elem = subarray[end_offset];
if end_offset < pivot_offset && insert_offset >= pivot_offset {
subarray.copy_within(pivot_offset..insert_offset, end_offset);
subarray[insert_offset - 1] = element;
self.start_indexes[subarray_idx] = end_offset;
} else {
subarray.copy_within(insert_offset..end_offset, insert_offset + 1);
subarray[insert_offset] = element;
}
debug_assert!(self.assert_invariants());
let max_subarray_idx = self.start_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.start_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 end_offset = if *pivot_offset_ref == 0 {
cur_subarray_idx
} else {
*pivot_offset_ref - 1
};
let end_idx = end_offset + Self::get_array_idx_from_subarray_idx(cur_subarray_idx);
let next_end_elem = self.data[end_idx];
self.data[end_idx] = prev_end_elem;
*pivot_offset_ref = end_offset;
prev_end_elem = next_end_elem;
}
if last_subarray_full {
self.data.push(prev_end_elem);
self.start_indexes.push(0);
} else {
let max_subarray_offset = Self::get_array_idx_from_subarray_idx(max_subarray_idx);
self.data.insert(max_subarray_offset, prev_end_elem);
}
debug_assert!(self.assert_invariants());
}
pub fn remove(&mut self, index: usize) -> T {
assert!(index < self.len());
let old_len = self.len();
let mut remove_idx = self.get_real_index(index);
let element = self.data[remove_idx];
let max_subarray_idx = self.start_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_start_offset = self.start_indexes[max_subarray_idx];
self.data[max_subarray_offset..].rotate_left(last_start_offset);
self.start_indexes[max_subarray_idx] = 0;
if subarray_idx == max_subarray_idx {
remove_idx = self.get_real_index(index);
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.start_indexes[subarray_idx];
let remove_offset = remove_idx - subarray_offset;
let end_offset = if pivot_offset == 0 {
subarray.len() - 1
} else {
pivot_offset - 1
};
let mut prev_end_offset = if end_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.start_indexes[subarray_idx] = new_pivot_offset;
pivot_offset
} else {
subarray.copy_within(remove_offset + 1..=end_offset, remove_offset);
end_offset
};
let next_subarray_idx = min(max_subarray_idx, subarray_idx + 1);
for (i, pivot_offset_ref) in self.start_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_end_idx =
prev_end_offset + Self::get_array_idx_from_subarray_idx(cur_subarray_idx - 1);
self.data[prev_end_idx] = self.data[cur_subarray_offset + *pivot_offset_ref];
prev_end_offset = *pivot_offset_ref;
let new_start_offset = if *pivot_offset_ref == cur_subarray_idx {
0
} else {
*pivot_offset_ref + 1
};
*pivot_offset_ref = new_start_offset;
}
let prev_end_idx =
prev_end_offset + Self::get_array_idx_from_subarray_idx(max_subarray_idx - 1);
self.data[prev_end_idx] = self.data[max_subarray_offset];
}
self.data.remove(max_subarray_remove_idx);
if max_subarray_offset == self.data.len() {
self.start_indexes.pop();
}
debug_assert!(self.len() == old_len - 1);
debug_assert!(self.assert_invariants());
element
}
pub fn append(&mut self, other: &mut Self) {
if !self.is_last_subarray_full() {
self.unrotate_last_subarray();
}
self.data.append(&mut other.data);
let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.data.len() - 1);
self.start_indexes.resize(last_subarray_idx + 1, 0);
other.clear();
}
pub fn sort(&mut self)
where T: Ord
{
self.data.sort();
for idx in self.start_indexes.as_mut_slice() {
*idx = 0;
}
}
pub fn sort_unstable(&mut self)
where T: Ord
{
self.data.sort_unstable();
for idx in self.start_indexes.as_mut_slice() {
*idx = 0;
}
}
fn get_real_index(&self, index: usize) -> usize {
debug_assert!(index < self.data.len());
let subarray_idx = Self::get_subarray_idx_from_array_idx(index);
let subarray_start_idx = Self::get_array_idx_from_subarray_idx(subarray_idx);
let subarray_len = if subarray_idx == self.start_indexes.len() - 1 {
self.data.len() - subarray_start_idx
} else {
subarray_idx + 1
};
debug_assert!(index >= subarray_start_idx);
let idx_offset = index - subarray_start_idx;
let pivot_offset = self.start_indexes[subarray_idx];
let rotated_offset = (pivot_offset + idx_offset) % subarray_len;
debug_assert!(rotated_offset < subarray_len);
let real_idx = subarray_start_idx + rotated_offset;
real_idx
}
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.start_indexes.len())
}
fn unrotate_last_subarray(&mut self) {
let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.len() - 1);
let last_subarray_start_idx = Self::get_array_idx_from_subarray_idx(last_subarray_idx);
let last_subarray_len = if last_subarray_idx == self.start_indexes.len() - 1 {
self.len() - last_subarray_start_idx
} else {
last_subarray_idx + 1
};
let last_subarray_end_idx = last_subarray_start_idx + last_subarray_len;
let last_subarray = &mut self.data[last_subarray_start_idx..last_subarray_end_idx];
let pivot_offset = self.start_indexes[last_subarray_idx];
last_subarray.rotate_left(pivot_offset);
self.start_indexes[last_subarray_idx] = 0;
}
#[inline(always)]
fn assert_invariants(&self) -> bool {
let expected_start_indexes_len = if self.is_empty() {
0
} else {
Self::get_subarray_idx_from_array_idx(self.len() - 1) + 1
};
assert_eq!(self.start_indexes.len(), expected_start_indexes_len);
assert!(self
.start_indexes
.iter()
.enumerate()
.all(|(idx, &offset)| offset <= idx));
true
}
fn init(&mut self) {
debug_assert!(self.start_indexes.is_empty());
if !self.data.is_empty() {
let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.data.len() - 1);
self.start_indexes = vec![0; last_subarray_idx + 1];
}
}
}
impl<T> PartialEq for RotatedVec<T>
where
T: Copy + Default + Debug + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for i in 0..self.len() {
if self.get(i).unwrap() != other.get(i).unwrap() {
return false;
}
}
true
}
}
impl<T> Eq for RotatedVec<T>
where
T: Copy + Default + Debug + PartialEq
{}
impl<T> PartialOrd for RotatedVec<T>
where
T: Copy + Default + Debug + PartialOrd
{
fn partial_cmp(&self, other: &RotatedVec<T>) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl<T> Ord for RotatedVec<T>
where
T: Copy + Default + Debug + Ord
{
fn cmp(&self, other: &RotatedVec<T>) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl<T> Hash for RotatedVec<T>
where
T: Copy + Default + Debug + PartialEq + Hash
{
fn hash<H: Hasher>(&self, state: &mut H) {
for i in 0..self.len() {
self.get(i).hash(state);
}
}
}
impl<T> Index<usize> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
type Output = T;
#[inline]
fn index(&self, index: usize) -> &T {
self.get(index).expect("Out of bounds access")
}
}
impl<T> IndexMut<usize> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
self.get_mut(index).expect("Out of bounds access")
}
}
impl<T> Extend<T> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
if !self.is_last_subarray_full() {
self.unrotate_last_subarray();
}
self.data.extend(iter);
let last_subarray_idx = Self::get_subarray_idx_from_array_idx(self.data.len() - 1);
self.start_indexes.resize(last_subarray_idx + 1, 0);
}
}
impl<'a, T> Iterator for Iter<'a, T>
where
T: 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.container.get(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.container.get(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.container.get(self.len() - 1)
}
}
fn max(self) -> Option<Self::Item> {
if self.len() == 0 {
None
} else {
self.container.get(self.len() - 1)
}
}
fn min(self) -> Option<Self::Item> {
self.container.get(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: 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.container.get(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.container.get(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: Copy + Default + Debug,
{
fn len(&self) -> usize {
self.container.len()
}
}
impl<T> FusedIterator for Iter<'_, T> where T: Copy + Default + Debug {}
impl<'a, T> Iterator for IterMut<'a, T>
where
T: Copy + Default + Debug,
{
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let ret = if self.len() == 0 || self.next_index > self.next_rev_index {
None
} else {
let current = self.container.get_mut(self.next_index);
self.next_index += 1;
unsafe { mem::transmute(current) }
};
debug_assert!(self.assert_invariants());
ret
}
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.container.get_mut(self.next_index);
self.next_index += 1;
unsafe { mem::transmute(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.container.get_mut(self.len() - 1)
}
}
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 IterMut<'a, T>
where
T: 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.container.get(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());
unsafe { mem::transmute(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.container.get(self.next_rev_index);
if self.next_rev_index == 0 {
self.next_index += 1;
} else {
self.next_rev_index -= 1;
}
unsafe { mem::transmute(nth) }
};
debug_assert!(self.assert_invariants());
ret
}
}
impl<T> ExactSizeIterator for IterMut<'_, T>
where
T: Copy + Default + Debug,
{
fn len(&self) -> usize {
self.container.len()
}
}
impl<T> FusedIterator for IterMut<'_, T> where T: Copy + Default + Debug {}
impl<'a, T> IntoIterator for &'a RotatedVec<T>
where
T: Copy + Default + Debug,
{
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut RotatedVec<T>
where
T: Copy + Default + Debug,
{
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T> IntoIterator for RotatedVec<T>
where
T: 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: 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)
}
}
}
impl<'a, T> From<&'a [T]> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
fn from(slice: &'a [T]) -> Self {
let mut this = RotatedVec {
data: slice.to_vec(),
start_indexes: Vec::new(),
};
this.init();
this
}
}
impl<T> From<Vec<T>> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
fn from(vec: Vec<T>) -> Self {
let mut this = RotatedVec {
data: vec,
start_indexes: Vec::new(),
};
this.init();
this
}
}
impl<T> Into<Vec<T>> for RotatedVec<T>
where
T: Copy + Default + Debug,
{
fn into(mut self) -> Vec<T> {
for (i, &pivot_offset) in self.start_indexes.iter().enumerate() {
let subarray_start_idx = Self::get_array_idx_from_subarray_idx(i);
let subarray_len = if i == self.start_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 RotatedVec<T>
where
T: Copy + Default + Debug,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut this = RotatedVec {
data: Vec::from_iter(iter.into_iter()),
start_indexes: Vec::new(),
};
this.init();
this
}
}
impl<T> Default for RotatedVec<T>
where
T: Copy + Default + Debug,
{
#[inline]
fn default() -> RotatedVec<T> {
RotatedVec::new()
}
}