use crate::{Sign, Signable};
use fastset::Set;
use nanorand::WyRand;
use serde::{Deserialize, Serialize};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::ops::{Bound, Deref, Index, RangeBounds};
const DEFAULT_SET_SIZE: usize = 1000;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SignVec<T>
where
T: Signable + Clone,
{
pub vals: Vec<T>,
pub pos: Set,
pub neg: Set,
_marker: PhantomData<T>,
}
impl<T> SignVec<T>
where
T: Signable + Clone,
{
#[inline(always)]
pub fn append(&mut self, other: &[T])
where
T: Signable + Clone,
{
let start_len = self.vals.len();
other.iter().enumerate().for_each(|(index, e)| {
let vals_index = start_len + index;
match e.sign() {
Sign::Plus => self.pos.insert(vals_index),
Sign::Minus => self.neg.insert(vals_index),
};
self.vals.push(e.clone());
});
}
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
self.vals.as_ptr()
}
#[inline(always)]
pub fn as_slice(&self) -> &[T] {
self.vals.as_slice()
}
#[inline(always)]
pub fn capacity(&self) -> usize {
self.vals.capacity()
}
#[inline(always)]
pub fn clear(&mut self) {
self.vals.clear();
self.pos.clear();
self.neg.clear();
}
#[inline(always)]
pub fn count(&self, sign: Sign) -> usize {
match sign {
Sign::Plus => self.pos.len(),
Sign::Minus => self.neg.len(),
}
}
#[inline(always)]
pub fn count_pos(&self) -> usize {
self.pos.len()
}
#[inline(always)]
pub fn count_neg(&self) -> usize {
self.neg.len()
}
#[inline(always)]
pub fn dedup(&mut self)
where
T: PartialEq + Signable,
{
if self.vals.is_empty() {
return;
}
let mut write = 1; for read in 1..self.vals.len() {
if self.vals[read] != self.vals[read - 1] {
if read != write {
self.vals[write] = self.vals[read].clone();
if self.vals[read].sign() == Sign::Plus {
self.pos.remove(&read);
self.pos.insert(write);
} else {
self.neg.remove(&read);
self.neg.insert(write);
}
}
write += 1;
} else {
self.pos.remove(&read);
self.neg.remove(&read);
}
}
self.vals.truncate(write);
}
#[inline(always)]
pub fn dedup_by<F>(&mut self, mut same_bucket: F)
where
F: FnMut(&T, &T) -> bool,
{
unsafe {
let mut len = self.vals.len();
let mut i = 0;
let vals_ptr = self.vals.as_mut_ptr();
while i < len {
let curr = vals_ptr.add(i);
let mut j = i + 1;
while j < len {
let next = vals_ptr.add(j);
if same_bucket(&*curr, &*next) {
self.vals.remove(j);
self.pos.remove(&j);
self.neg.remove(&j);
len -= 1;
} else {
j += 1;
}
}
i += 1;
}
}
}
#[inline(always)]
pub fn dedup_by_key<F, K>(&mut self, mut key: F)
where
F: FnMut(&T) -> K,
K: PartialEq,
{
unsafe {
let mut i = 1;
let vals_ptr = self.vals.as_mut_ptr();
while i < self.vals.len() {
let prev = vals_ptr.add(i - 1);
let now = vals_ptr.add(i);
if i > 0 && key(&*prev) == key(&*now) {
self.vals.remove(i); self.pos.remove(&(i));
self.neg.remove(&(i));
} else {
i += 1; }
}
}
}
#[inline(always)]
pub fn drain<R>(&mut self, range: R) -> SignVecDrain<'_, T>
where
R: RangeBounds<usize>,
{
let start = match range.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + 1,
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(&e) => e + 1,
Bound::Excluded(&e) => e,
Bound::Unbounded => self.vals.len(),
};
if start > end || end > self.vals.len() {
panic!("Drain range out of bounds");
}
SignVecDrain {
sign_vec: self,
current_index: start,
drain_end: end,
}
}
#[inline(always)]
pub fn extend_from_slice(&mut self, other: &[T]) {
let offset = self.vals.len();
self.vals.extend_from_slice(other);
for (i, e) in other.iter().enumerate() {
match e.sign() {
Sign::Plus => self.pos.insert(offset + i),
Sign::Minus => self.neg.insert(offset + i),
};
}
}
#[inline(always)]
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
{
let start = match src.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + 1,
Bound::Unbounded => 0,
};
let end = match src.end_bound() {
Bound::Included(&e) => e + 1,
Bound::Excluded(&e) => e,
Bound::Unbounded => self.vals.len(),
};
if start > end || end > self.vals.len() {
panic!("Invalid range for extend_from_within");
}
let offset = self.vals.len();
self.vals.extend_from_within(start..end);
for i in start..end {
match self.vals[i].sign() {
Sign::Plus => self.pos.insert(offset + i - start),
Sign::Minus => self.neg.insert(offset + i - start),
};
}
}
#[inline(always)]
pub fn insert(&mut self, index: usize, element: T) {
self.pos = self
.pos
.iter()
.map(|&idx| if idx >= index { idx + 1 } else { idx })
.collect();
self.neg = self
.neg
.iter()
.map(|&idx| if idx >= index { idx + 1 } else { idx })
.collect();
match element.sign() {
Sign::Plus => {
self.pos.insert(index);
}
Sign::Minus => {
self.neg.insert(index);
}
};
self.vals.insert(index, element);
}
#[inline(always)]
pub fn indices(&self, sign: Sign) -> &Set {
match sign {
Sign::Plus => &self.pos,
Sign::Minus => &self.neg,
}
}
#[inline(always)]
pub fn indices_pos(&self) -> &Set {
&self.pos
}
#[inline(always)]
pub fn indices_neg(&self) -> &Set {
&self.neg
}
#[inline(always)]
pub fn into_boxed_slice(self) -> Box<[T]> {
self.vals.into_boxed_slice()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.vals.is_empty()
}
#[inline(always)]
pub fn leak<'a>(self) -> &'a mut [T] {
let pointer = self.vals.as_ptr();
let len = self.vals.len();
std::mem::forget(self);
unsafe { std::slice::from_raw_parts_mut(pointer as *mut T, len) }
}
#[inline(always)]
pub fn len(&self) -> usize {
self.vals.len()
}
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
pub fn pop(&mut self) -> Option<T> {
if let Some(topop) = self.vals.pop() {
let idx = self.vals.len(); match topop.sign() {
Sign::Plus => {
self.pos.remove(&idx);
}
Sign::Minus => {
self.neg.remove(&idx);
}
};
Some(topop)
} else {
None
}
}
#[inline(always)]
pub fn push(&mut self, element: T) {
let index = self.vals.len();
match element.sign() {
Sign::Plus => self.pos.insert(index),
Sign::Minus => self.neg.insert(index),
};
self.vals.push(element);
}
#[inline(always)]
pub fn remove(&mut self, index: usize) -> T {
self.pos = self
.pos
.iter()
.map(|&idx| if idx > index { idx - 1 } else { idx })
.collect();
self.neg = self
.neg
.iter()
.map(|&idx| if idx > index { idx - 1 } else { idx })
.collect();
let removed = self.vals.remove(index);
match removed.sign() {
Sign::Plus => self.pos.remove(&index),
Sign::Minus => self.neg.remove(&index),
};
removed
}
#[inline(always)]
pub fn reserve(&mut self, additional: usize) {
let new_capacity = self.vals.len() + additional;
self.vals.reserve(additional);
self.pos.reserve(new_capacity);
self.neg.reserve(new_capacity);
}
#[inline(always)]
pub fn reserve_exact(&mut self, additional: usize) {
let new_capacity = self.vals.len() + additional;
self.vals.reserve_exact(additional);
self.pos.reserve(new_capacity);
self.neg.reserve(new_capacity);
}
#[inline(always)]
pub fn resize(&mut self, new_len: usize, value: T) {
let old_len = self.vals.len();
match new_len > old_len {
true => {
self.vals.resize(new_len, value.clone());
match value.sign() {
Sign::Plus => (old_len..new_len).for_each(|i| {
self.pos.insert(i);
}),
Sign::Minus => (old_len..new_len).for_each(|i| {
self.neg.insert(i);
}),
};
}
false => {
(new_len..old_len).for_each(|i| {
self.pos.remove(&i);
self.neg.remove(&i);
});
self.vals.truncate(new_len);
}
}
}
#[inline(always)]
pub fn resize_with<F>(&mut self, new_len: usize, mut f: F)
where
F: FnMut() -> T,
{
let old_len = self.vals.len();
match new_len > old_len {
true => {
(old_len..new_len).for_each(|i| {
let value = f();
match value.sign() {
Sign::Plus => self.pos.insert(i),
Sign::Minus => self.neg.insert(i),
};
self.vals.push(value);
});
}
false => {
(new_len..old_len).for_each(|i| {
self.pos.remove(&i);
self.neg.remove(&i);
});
self.vals.truncate(new_len);
}
}
}
#[inline(always)]
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&T) -> bool,
{
self.vals.retain(f);
self.sync();
}
#[inline(always)]
pub fn retain_mut<F>(&mut self, f: F)
where
F: FnMut(&mut T) -> bool,
{
self.vals.retain_mut(f);
self.sync();
}
#[inline(always)]
pub fn random(&self, sign: Sign, rng: &mut WyRand) -> Option<usize> {
match sign {
Sign::Plus => self.pos.random(rng),
Sign::Minus => self.neg.random(rng),
}
}
#[inline(always)]
pub fn random_pos(&self, rng: &mut WyRand) -> Option<usize> {
self.pos.random(rng)
}
#[inline(always)]
pub fn random_neg(&self, rng: &mut WyRand) -> Option<usize> {
self.neg.random(rng)
}
pub unsafe fn set_len(&mut self, new_len: usize) {
if new_len > self.vals.capacity() {
panic!("new_len out of bounds: new_len must be less than or equal to capacity()");
}
let old_len = self.vals.len();
match new_len.cmp(&old_len) {
std::cmp::Ordering::Greater => {
self.vals.set_len(new_len);
let vals_ptr = self.vals.as_mut_ptr();
(old_len..new_len).for_each(|i| {
match unsafe { &*vals_ptr.add(i) }.sign() {
Sign::Plus => {
self.pos.insert(i);
}
Sign::Minus => {
self.neg.insert(i);
}
}
});
}
std::cmp::Ordering::Less => {
(new_len..old_len).for_each(|i| {
self.pos.remove(&i);
self.neg.remove(&i);
});
self.vals.set_len(new_len);
}
std::cmp::Ordering::Equal => {
}
}
}
#[inline(always)]
pub fn set(&mut self, idx: usize, val: T) {
if idx >= self.vals.len() {
panic!(
"Index out of bounds: index {} length {}",
idx,
self.vals.len()
);
}
unsafe {
self.set_unchecked(idx, val);
}
}
#[inline(always)]
pub unsafe fn set_unchecked(&mut self, idx: usize, mut val: T) {
let old_val = &mut *self.vals.as_mut_ptr().add(idx);
let old_sign = old_val.sign();
let new_sign = val.sign();
std::mem::swap(old_val, &mut val);
if old_sign != new_sign {
match new_sign {
Sign::Plus => {
self.neg.remove(&idx);
self.pos.insert(idx);
}
Sign::Minus => {
self.pos.remove(&idx);
self.neg.insert(idx);
}
}
}
}
#[inline(always)]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.vals.shrink_to(min_capacity);
self.pos.shrink_to(min_capacity);
self.neg.shrink_to(min_capacity);
}
#[inline(always)]
pub fn shrink_to_fit(&mut self) {
self.vals.shrink_to_fit();
self.pos.shrink_to_fit();
self.neg.shrink_to_fit();
}
#[inline(always)]
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
let len = self.vals.len();
let capacity = self.vals.capacity();
unsafe {
std::slice::from_raw_parts_mut(
self.vals.as_mut_ptr().add(len) as *mut MaybeUninit<T>,
capacity - len,
)
}
}
pub fn split_off(&mut self, at: usize) -> SignVec<T> {
if at > self.vals.len() {
panic!(
"split_off at index out of bounds: the length is {} but the split index is {}",
self.vals.len(),
at
);
}
let new_vals = self.vals.split_off(at);
let mut new_pos = Set::with_max(new_vals.len());
let mut new_neg = Set::with_max(new_vals.len());
(0..new_vals.len()).for_each(|i| {
if self.pos.contains(&(at + i)) {
self.pos.remove(&(at + i));
new_pos.insert(i);
} else if self.neg.remove(&(at + i)) {
new_neg.insert(i);
}
});
SignVec {
vals: new_vals,
pos: new_pos,
neg: new_neg,
_marker: PhantomData,
}
}
#[inline(always)]
pub fn swap_remove(&mut self, index: usize) -> T {
let removed_element = self.vals.swap_remove(index);
let sign = removed_element.sign();
match sign {
Sign::Plus => self.pos.remove(&index),
Sign::Minus => self.neg.remove(&index),
};
if index < self.vals.len() {
let swapped_element_sign = self.vals[index].sign();
match swapped_element_sign {
Sign::Plus => {
self.pos.remove(&self.vals.len());
self.pos.insert(index);
}
Sign::Minus => {
self.neg.remove(&self.vals.len());
self.neg.insert(index);
}
}
}
removed_element
}
#[inline(always)]
pub fn sync(&mut self) {
self.pos.clear();
self.neg.clear();
self.vals.iter().enumerate().for_each(|(idx, val)| {
match val.sign() {
Sign::Plus => self.pos.insert(idx),
Sign::Minus => self.neg.insert(idx),
};
});
}
#[inline(always)]
pub fn truncate(&mut self, len: usize) {
if len < self.vals.len() {
let old_len = self.vals.len();
unsafe {
let vals_ptr = self.vals.as_ptr();
for i in len..old_len {
let val = &*vals_ptr.add(i);
match val.sign() {
Sign::Plus => self.pos.remove(&i),
Sign::Minus => self.neg.remove(&i),
};
}
}
self.vals.truncate(len);
}
}
pub fn try_reserve(
&mut self,
additional: usize,
) -> Result<(), std::collections::TryReserveError> {
self.vals.try_reserve(additional)?;
self.pos.reserve(self.vals.len() + additional);
self.neg.reserve(self.vals.len() + additional);
Ok(())
}
pub fn try_reserve_exact(
&mut self,
additional: usize,
) -> Result<(), std::collections::TryReserveError> {
self.vals.try_reserve_exact(additional)?;
self.pos.reserve(self.vals.len() + additional);
self.neg.reserve(self.vals.len() + additional);
Ok(())
}
#[inline(always)]
pub fn values(&self, sign: Sign) -> SignVecValues<T> {
SignVecValues::new(self, sign)
}
#[inline(always)]
pub fn with_capacity(capacity: usize) -> Self {
Self {
vals: Vec::with_capacity(capacity),
pos: Set::with_max(capacity),
neg: Set::with_max(capacity),
_marker: PhantomData,
}
}
}
pub struct SignVecDrain<'a, T: 'a + Clone + Signable> {
sign_vec: &'a mut SignVec<T>,
current_index: usize,
drain_end: usize,
}
impl<'a, T> Iterator for SignVecDrain<'a, T>
where
T: Signable + Clone,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.current_index >= self.drain_end {
return None;
}
let result = self.sign_vec.vals.remove(self.current_index);
self.sign_vec.pos.remove(&self.current_index);
self.sign_vec.neg.remove(&self.current_index);
self.sign_vec.pos = self
.sign_vec
.pos
.iter()
.map(|&i| if i > self.current_index { i - 1 } else { i })
.collect();
self.sign_vec.neg = self
.sign_vec
.neg
.iter()
.map(|&i| if i > self.current_index { i - 1 } else { i })
.collect();
self.drain_end -= 1;
Some(result)
}
}
#[derive(Debug)]
pub struct SignVecValues<'a, T>
where
T: 'a + Signable + Clone,
{
vals_ptr: *const T,
indices_iter: std::slice::Iter<'a, usize>,
}
impl<'a, T> SignVecValues<'a, T>
where
T: Signable + Clone,
{
#[inline(always)]
pub fn new(sign_vec: &'a SignVec<T>, sign: Sign) -> Self {
let vals_ptr = sign_vec.vals.as_ptr();
let indices_iter = match sign {
Sign::Plus => (&sign_vec.pos).into_iter(),
Sign::Minus => (&sign_vec.neg).into_iter(),
};
SignVecValues {
vals_ptr,
indices_iter,
}
}
}
impl<'a, T> Iterator for SignVecValues<'a, T>
where
T: 'a + Signable + Clone,
{
type Item = &'a T;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.indices_iter.next().map(|&idx|
unsafe { &*self.vals_ptr.add(idx) })
}
}
impl<T> AsRef<Vec<T>> for SignVec<T>
where
T: Signable + Clone,
{
fn as_ref(&self) -> &Vec<T> {
&self.vals
}
}
impl<T> Default for SignVec<T>
where
T: Signable + Clone,
{
fn default() -> Self {
Self {
vals: Vec::default(),
pos: Set::with_max(DEFAULT_SET_SIZE),
neg: Set::with_max(DEFAULT_SET_SIZE),
_marker: PhantomData,
}
}
}
impl<'a, T> Extend<&'a T> for SignVec<T>
where
T: Signable + Clone + 'a,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = &'a T>,
{
for item in iter {
let index = self.vals.len(); self.vals.push(item.clone()); match item.sign() {
Sign::Plus => {
self.pos.insert(index);
}
Sign::Minus => {
self.neg.insert(index);
}
}
}
}
}
impl<T> Extend<T> for SignVec<T>
where
T: Signable + Clone,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
for item in iter {
let index = self.vals.len(); match item.sign() {
Sign::Plus => {
self.pos.insert(index);
}
Sign::Minus => {
self.neg.insert(index);
}
}
self.vals.push(item); }
}
}
impl<T> From<&[T]> for SignVec<T>
where
T: Signable + Clone,
{
fn from(slice: &[T]) -> Self {
slice.iter().cloned().collect()
}
}
impl<T, const N: usize> From<&[T; N]> for SignVec<T>
where
T: Signable + Clone,
{
fn from(array: &[T; N]) -> Self {
array.iter().cloned().collect()
}
}
impl<T> From<&mut [T]> for SignVec<T>
where
T: Signable + Clone,
{
fn from(slice: &mut [T]) -> Self {
slice.iter().cloned().collect()
}
}
impl<T, const N: usize> From<&mut [T; N]> for SignVec<T>
where
T: Signable + Clone,
{
fn from(array: &mut [T; N]) -> Self {
array.iter().cloned().collect()
}
}
impl<T> From<&Vec<T>> for SignVec<T>
where
T: Signable + Clone,
{
fn from(vec: &Vec<T>) -> Self {
vec.iter().cloned().collect()
}
}
impl<T> From<Vec<T>> for SignVec<T>
where
T: Signable + Clone,
{
fn from(vec: Vec<T>) -> Self {
vec.into_iter().collect()
}
}
impl<T> From<SignVec<T>> for Vec<T>
where
T: Signable + Clone,
{
fn from(sign_vec: SignVec<T>) -> Self {
sign_vec.vals.clone()
}
}
impl<T> From<&SignVec<T>> for Vec<T>
where
T: Signable + Clone,
{
fn from(sign_vec: &SignVec<T>) -> Self {
sign_vec.vals.clone()
}
}
impl<T, const N: usize> From<[T; N]> for SignVec<T>
where
T: Signable + Clone,
{
fn from(array: [T; N]) -> Self {
array.into_iter().collect()
}
}
impl<T> FromIterator<T> for SignVec<T>
where
T: Signable + Clone,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut vec = Vec::new();
let mut pos = Set::with_max(DEFAULT_SET_SIZE);
let mut neg = Set::with_max(DEFAULT_SET_SIZE);
for (i, item) in iter.into_iter().enumerate() {
if item.sign() == Sign::Plus {
pos.insert(i);
} else {
neg.insert(i);
}
vec.push(item);
}
SignVec {
vals: vec,
pos,
neg,
_marker: PhantomData,
}
}
}
impl<'a, T> FromIterator<&'a T> for SignVec<T>
where
T: 'a + Signable + Clone,
{
fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self {
let mut vec = Vec::new();
let mut pos = Set::with_max(DEFAULT_SET_SIZE);
let mut neg = Set::with_max(DEFAULT_SET_SIZE);
for (i, item) in iter.into_iter().enumerate() {
let cloned_item = item.clone();
if cloned_item.sign() == Sign::Plus {
pos.insert(i);
} else {
neg.insert(i);
}
vec.push(cloned_item);
}
SignVec {
vals: vec,
pos,
neg,
_marker: PhantomData,
}
}
}
impl<T> IntoIterator for SignVec<T>
where
T: Signable + Clone,
{
type Item = T;
type IntoIter = ::std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.vals.into_iter()
}
}
impl<'a, T> IntoIterator for &'a SignVec<T>
where
T: Signable + Clone,
{
type Item = &'a T;
type IntoIter = ::std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.vals.iter()
}
}
impl<'a, T> IntoIterator for &'a mut SignVec<T>
where
T: Signable + Clone,
{
type Item = &'a mut T;
type IntoIter = ::std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.vals.iter_mut()
}
}
impl<T> Index<usize> for SignVec<T>
where
T: Signable + Clone,
{
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.vals[index]
}
}
impl<T> Deref for SignVec<T>
where
T: Signable + Clone,
{
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.vals
}
}
impl<T> Borrow<[T]> for SignVec<T>
where
T: Signable + Clone,
{
fn borrow(&self) -> &[T] {
&self.vals
}
}
impl<T> Hash for SignVec<T>
where
T: Signable + Clone + Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.vals.len().hash(state);
for item in &self.vals {
item.hash(state);
}
}
}
impl<T> Ord for SignVec<T>
where
T: Signable + Clone + Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
self.vals.cmp(&other.vals)
}
}
impl<T> PartialOrd for SignVec<T>
where
T: Signable + Clone + PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.vals.partial_cmp(&other.vals)
}
}
impl<T> Eq for SignVec<T> where T: Signable + Clone + Eq {}
impl<T> PartialEq for SignVec<T>
where
T: Signable + Clone + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.vals.eq(&other.vals)
}
}
impl<T, U> PartialEq<&[U]> for SignVec<T>
where
T: PartialEq<U> + Signable + Clone,
{
fn eq(&self, other: &&[U]) -> bool {
self.vals.eq(other)
}
}
impl<T, U> PartialEq<&mut [U]> for SignVec<T>
where
T: PartialEq<U> + Signable + Clone,
{
fn eq(&self, other: &&mut [U]) -> bool {
self.vals.eq(*other)
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for SignVec<T>
where
T: PartialEq<U> + Signable + Clone,
{
fn eq(&self, other: &[U; N]) -> bool {
self.vals.eq(other)
}
}
impl<T, U> PartialEq<Vec<U>> for SignVec<T>
where
T: PartialEq<U> + Signable + Clone,
{
fn eq(&self, other: &Vec<U>) -> bool {
self.vals.eq(other)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::svec;
use fastset::set;
use std::collections::HashSet;
#[derive(Clone, Eq, PartialEq, Default)]
struct Account {
balance: i32, }
impl Account {
fn new(balance: i32) -> Self {
Account { balance }
}
fn balance(&self) -> i32 {
self.balance
}
}
impl Signable for Account {
fn sign(&self) -> Sign {
if self.balance >= 0 {
Sign::Plus
} else {
Sign::Minus
}
}
}
#[test]
fn test_append() {
let mut vec = svec![-1];
let other = vec![2, -3];
vec.append(&other);
assert_eq!(vec.as_slice(), &[-1, 2, -3]);
assert_eq!(vec.count(Sign::Plus), 1);
assert_eq!(vec.count(Sign::Minus), 2);
let mut vec = svec![];
let other = vec![-2, 3];
vec.append(&other);
assert_eq!(vec.as_slice(), &[-2, 3]);
assert_eq!(vec.count(Sign::Plus), 1);
assert_eq!(vec.count(Sign::Minus), 1);
}
#[test]
fn test_as_ptr() {
let vec: SignVec<i32> = svec![1, -2, 3];
let ptr = vec.as_ptr();
unsafe {
assert_eq!(*ptr, 1); assert_eq!(*ptr.offset(1), -2); assert_eq!(*ptr.offset(2), 3); }
}
#[test]
fn test_as_slice() {
let vec = svec![1, -2, 3];
let slice = vec.as_slice();
assert_eq!(slice, &[1, -2, 3]);
}
#[test]
fn test_capacity() {
let vec = SignVec::<i32>::with_capacity(10);
assert_eq!(vec.capacity(), 10);
}
#[test]
fn test_clear() {
let mut vec = svec![1, -2, 3];
vec.clear();
assert!(vec.is_empty());
assert_eq!(vec.capacity(), 4);
}
#[test]
fn test_count() {
let mut vec = svec![1, -2, 3, -4];
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 2);
vec.push(5);
assert_eq!(vec.count(Sign::Plus), 3);
assert_eq!(vec.count(Sign::Minus), 2);
}
#[test]
fn test_dedup() {
let mut vec = svec![1, 2, 2, -3, -3, 4];
vec.dedup();
assert_eq!(vec.as_slice(), &[1, 2, -3, 4]);
let mut vec = svec![1, 2, -2, -3, -3, 4];
vec.dedup();
assert_eq!(vec.as_slice(), &[1, 2, -2, -3, 4]);
}
#[test]
fn test_dedup_by() {
let mut vec = svec![10, -5, 10, -5];
vec.dedup_by(|a, b| a == b);
assert_eq!(vec.as_slice(), &[10, -5]);
let mut vec = svec![
Account::new(100),
Account::new(-50),
Account::new(100),
Account::new(-50),
];
vec.dedup_by(|a, b| a.balance() == b.balance());
assert_eq!(vec.as_slice().len(), 2);
}
#[test]
fn test_dedup_by_key() {
let mut vec = svec![
Account::new(100),
Account::new(100),
Account::new(-50),
Account::new(-50),
];
vec.dedup_by_key(|a| a.balance());
assert_eq!(vec.as_slice().len(), 2);
}
#[test]
fn test_drain() {
let mut vec = svec![1, 2, 3, 4, 5];
let drained_elements: Vec<_> = vec.drain(1..4).collect();
assert_eq!(drained_elements, vec![2, 3, 4]);
assert_eq!(vec.as_slice(), &[1, 5]);
let mut vec = svec![1, 2, 3, 4, 5];
let drained_elements: Vec<_> = vec.drain(..).collect();
assert_eq!(drained_elements, vec![1, 2, 3, 4, 5]);
assert!(vec.is_empty());
let mut vec = svec![1, 2, 3, 4, 5];
let drained_elements: Vec<_> = vec.drain(5..5).collect();
assert!(drained_elements.is_empty());
assert_eq!(vec.as_slice(), &[1, 2, 3, 4, 5]);
let mut vec = svec![1, 2, 3, 4, 5];
let drained_elements: Vec<_> = vec.drain(..=2).collect();
assert_eq!(drained_elements, vec![1, 2, 3]);
assert_eq!(vec.as_slice(), &[4, 5]);
}
#[test]
fn test_extend_from_slice() {
let mut vec = svec![];
let other = vec![1, 2, 3];
vec.extend_from_slice(&other);
assert_eq!(vec.as_slice(), &[1, 2, 3]);
}
#[test]
fn test_extend_from_within() {
let mut vec = svec![0, 1, 2, 3, 4];
vec.extend_from_within(2..);
assert_eq!(vec.as_slice(), &[0, 1, 2, 3, 4, 2, 3, 4]);
vec.extend_from_within(5..);
assert_eq!(vec.as_slice(), &[0, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4]);
}
#[test]
fn test_insert() {
let mut vec = svec![1, 2, 3];
vec.insert(1, 4);
assert_eq!(vec.as_slice(), &[1, 4, 2, 3]);
assert_eq!(vec.count(Sign::Plus), 4);
}
#[test]
fn test_indices() {
let vec = svec![1, -2, 3, -4, 5];
assert_eq!(vec.indices(Sign::Plus), &Set::from(vec![0, 2, 4]));
assert_eq!(vec.indices(Sign::Minus), &Set::from(vec![1, 3]));
}
#[test]
fn test_into_boxed_slice() {
let vec = svec![1, 2, 3];
let boxed_slice: Box<[i32]> = vec.into_boxed_slice();
assert_eq!(&*boxed_slice, &[1, 2, 3]);
}
#[test]
fn test_is_empty() {
let vec = SignVec::<i32>::new();
assert!(vec.is_empty());
}
#[test]
fn test_leak() {
let vec = svec![1, 2, 3];
let leaked_slice = vec.leak();
assert_eq!(leaked_slice, &[1, 2, 3]);
}
#[test]
fn test_len() {
let vec = svec![1, 2, 3];
assert_eq!(vec.len(), 3);
}
#[test]
fn test_new() {
let mut sv: SignVec<i32> = SignVec::new();
let input = vec![1, -2, 3, -4, 5];
input.iter().for_each(|&i| {
sv.push(i);
});
assert_eq!(sv.vals, input);
assert_eq!(sv.as_slice(), &[1, -2, 3, -4, 5]);
assert_eq!(sv.count(Sign::Plus), 3);
assert_eq!(sv.count(Sign::Minus), 2);
}
#[test]
fn test_pop() {
let mut vec = svec![1, 2, -3, 4];
assert_eq!(vec.len(), 4);
assert!(vec.indices(Sign::Plus).contains(&3));
assert_eq!(vec.pop(), Some(4));
assert_eq!(vec.len(), 3);
assert!(!vec.indices(Sign::Plus).contains(&3));
assert_eq!(vec.indices(Sign::Plus), &set![0, 1]);
assert_eq!(vec.indices(Sign::Minus), &set![2]);
assert_eq!(vec.pop(), Some(-3));
assert_eq!(vec.len(), 2);
assert!(!vec.indices(Sign::Minus).contains(&2));
assert_eq!(vec.indices(Sign::Plus), &set![0, 1]);
assert_eq!(vec.indices(Sign::Minus), &set![]);
}
#[test]
fn test_push() {
let mut vec = svec![];
vec.push(1);
vec.push(-2);
vec.push(3);
assert_eq!(vec.as_slice(), &[1, -2, 3]);
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 1);
}
#[test]
fn test_remove() {
let mut vec = svec![1, -2, 3];
vec.remove(1);
assert_eq!(vec.as_slice(), &[1, 3]);
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 0);
}
#[test]
fn test_reserve() {
let mut vec = svec![1, -2, 3];
vec.reserve(5);
assert!(vec.capacity() >= 5);
}
#[test]
fn test_reserve_exact() {
let mut vec = svec![1, -2, 3];
vec.reserve_exact(5);
assert!(vec.capacity() >= 8);
}
#[test]
fn test_resize() {
let mut vec = svec![1, -2, 3];
vec.resize(5, 0);
assert_eq!(vec.as_slice(), &[1, -2, 3, 0, 0]);
assert_eq!(vec.count(Sign::Plus), 4);
assert_eq!(vec.count(Sign::Minus), 1);
}
#[test]
fn test_resize_with() {
let mut vec = svec![1, -2, 3];
vec.resize_with(5, || -1);
assert_eq!(vec.as_slice(), &[1, -2, 3, -1, -1]);
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 3);
}
#[test]
fn test_retain() {
let mut vec = svec![1, -2, 3];
vec.retain(|&x| x > 0);
assert_eq!(vec.as_slice(), &[1, 3]);
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 0);
}
#[test]
fn test_retain_mut() {
let mut vec = svec![1, -2, 3];
vec.retain_mut(|x| *x > 0);
assert_eq!(vec.as_slice(), &[1, 3]);
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 0);
}
#[test]
fn test_random() {
let mut svec = svec![1, -1, 2, -2, 3];
let mut rng = WyRand::new();
let mut observed_values = HashSet::new();
for _ in 0..100 {
if let Some(value) = svec.random(Sign::Plus, &mut rng) {
assert!(
svec.pos.contains(&value),
"Randomly selected value should be in the set"
);
observed_values.insert(value);
}
}
assert!(
observed_values.len() > 1,
"Random should return different values over multiple calls"
);
svec.clear();
assert!(
svec.random(Sign::Minus, &mut rng).is_none(),
"Random should return None for an empty set"
);
assert!(
svec.random(Sign::Plus, &mut rng).is_none(),
"Random should return None for an empty set"
);
}
#[test]
fn test_set_len() {
let mut vec = svec![1, -2, 3];
vec.resize(5, 0); unsafe {
vec.set_len(5);
}
assert_eq!(vec.as_slice(), &[1, -2, 3, 0, 0]);
assert_eq!(vec.count(Sign::Plus), 4);
assert_eq!(vec.count(Sign::Minus), 1);
unsafe {
vec.set_len(2);
}
assert_eq!(vec.as_slice(), &[1, -2]);
assert_eq!(vec.count(Sign::Plus), 1);
assert_eq!(vec.count(Sign::Minus), 1);
}
#[test]
#[should_panic(expected = "new_len out of bounds")]
fn test_set_len_out_of_bounds() {
let mut vec = svec![1, -2, 3];
unsafe {
vec.set_len(10);
} }
#[test]
fn test_set_unchecked() {
let mut vec = svec![1, -2, 3];
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 1);
unsafe {
vec.set_unchecked(1, 5); }
assert_eq!(vec.as_slice(), &[1, 5, 3]);
assert_eq!(vec.count(Sign::Plus), 3);
assert_eq!(vec.count(Sign::Minus), 0);
}
#[test]
#[should_panic(expected = "Index out of bounds")]
fn test_set_out_of_bounds() {
let mut vec = svec![1, -2, 3];
vec.set(10, 5); }
#[test]
fn test_shrink_to() {
let mut vec = SignVec::<i32>::with_capacity(10);
vec.extend_from_slice(&[1, -2, 3]);
assert!(vec.capacity() >= 10);
vec.shrink_to(5);
assert!(vec.capacity() >= 5);
vec.shrink_to(0);
assert!(vec.capacity() >= 3);
}
#[test]
fn test_shrink_to_fit() {
let mut vec = svec![1, -2, 3];
vec.reserve(10); vec.shrink_to_fit();
assert_eq!(vec.capacity(), 3);
}
#[test]
fn test_spare_capacity_mut() {
let mut vec = svec![1, -2, 3];
vec.reserve(10); let expected_spare_capacity = vec.capacity() - vec.len();
let spare_capacity = vec.spare_capacity_mut();
assert_eq!(spare_capacity.len(), expected_spare_capacity); }
#[test]
fn test_split_off() {
let mut vec = svec![1, -2, 3];
vec.push(4);
let new_vec = vec.split_off(2);
assert_eq!(vec.len(), 2);
assert_eq!(new_vec.len(), 2);
assert_eq!(vec.as_slice(), &[1, -2]);
assert_eq!(new_vec.as_slice(), &[3, 4]);
}
#[test]
fn test_swap_remove() {
let mut vec = svec![1, -2, 3];
let removed = vec.swap_remove(1);
assert_eq!(removed, -2);
assert_eq!(vec.len(), 2);
assert_eq!(vec.as_slice(), &[1, 3]);
}
#[test]
fn test_sync() {
let mut vec = svec![1, -2, 3];
vec.remove(1); vec.sync();
assert_eq!(vec.count(Sign::Plus), 2);
assert_eq!(vec.count(Sign::Minus), 0);
let mut vec2 = svec![1, -1, 2];
vec2.vals[0] = -3; vec2.sync();
assert!(vec2.indices(Sign::Plus).contains(&2));
assert!(vec2.indices(Sign::Minus).contains(&0));
}
#[test]
fn test_truncate() {
let mut vec = svec![1, -2, 3];
vec.truncate(2);
assert_eq!(vec.len(), 2);
assert_eq!(vec.as_slice(), &[1, -2]);
}
#[test]
fn test_try_reserve() {
let mut vec = svec![1, -2, 3];
vec.try_reserve(2).unwrap();
assert!(vec.capacity() >= 5);
vec.try_reserve_exact(3).unwrap();
assert!(vec.capacity() >= 6); }
#[test]
fn test_values() {
let vec = svec![1, -2, 3];
assert_eq!(vec.values(Sign::Plus).collect::<Vec<_>>(), vec![&1, &3]);
assert_eq!(vec.values(Sign::Minus).collect::<Vec<_>>(), vec![&-2]);
}
#[test]
fn test_with_capacity() {
let vec = SignVec::<i32>::with_capacity(5);
assert_eq!(vec.capacity(), 5);
assert_eq!(vec.len(), 0);
}
#[test]
fn test_set_and_set_unchecked() {
let mut sign_vec = svec![1, -1, 2];
sign_vec.set(1, 3); assert_eq!(sign_vec.vals[1], 3);
}
#[test]
fn test_len_and_is_empty() {
let vec = SignVec::<i32>::new();
assert_eq!(vec.len(), 0);
assert!(vec.is_empty());
let vec = svec![1, -1];
assert_eq!(vec.len(), 2);
assert!(!vec.is_empty());
}
#[test]
fn test_indices_values_count() {
let vec = svec![1, -1, 2, -2, 3];
assert_eq!(vec.count(Sign::Plus), 3);
assert_eq!(vec.count(Sign::Minus), 2);
let plus_indices: Vec<usize> = vec.indices(Sign::Plus).iter().copied().collect();
assert_eq!(plus_indices, vec![0, 2, 4]);
let minus_values: Vec<&i32> = vec.values(Sign::Minus).collect();
assert_eq!(minus_values, vec![&-1, &-2]);
}
#[test]
fn test_capacity_and_with_capacity() {
let vec = SignVec::<isize>::with_capacity(10);
assert!(vec.capacity() >= 10);
}
#[test]
fn test_reserve_and_reserve_exact() {
let mut vec = svec![1, -1, 2];
vec.reserve(8);
assert!(vec.capacity() >= 10);
vec.reserve_exact(20);
assert!(vec.capacity() >= 20);
}
#[test]
fn test_shrink_to_fit_and_shrink_to() {
let mut vec = SignVec::with_capacity(10);
vec.push(1);
vec.push(-1);
vec.shrink_to_fit();
assert_eq!(vec.capacity(), 2);
vec.shrink_to(10);
assert!(vec.capacity() >= 2);
}
#[test]
fn test_into_boxed_slice_and_truncate() {
let mut vec = svec![1, -1, 2, -2, 3];
vec.truncate(3);
assert_eq!(vec.len(), 3);
let boxed_slice = vec.into_boxed_slice();
assert_eq!(boxed_slice.len(), 3);
}
#[test]
fn test_as_slice_and_as_ptr() {
let vec = svec![1, -1, 2];
let slice = vec.as_slice();
assert_eq!(slice, &[1, -1, 2]);
let ptr = vec.as_ptr();
unsafe {
assert_eq!(*ptr, 1);
}
}
#[test]
fn test_swap_remove_and_remove() {
let mut vec = svec![1, -1, 2];
assert_eq!(vec.swap_remove(1), -1);
assert_eq!(vec.len(), 2);
assert_eq!(vec.remove(0), 1);
assert_eq!(vec.len(), 1);
}
#[test]
fn test_push_and_append() {
let mut vec = svec![1, 2];
vec.push(-1);
assert_eq!(vec.len(), 3);
assert!(vec.indices(Sign::Minus).contains(&2));
let other = vec![3, -2];
vec.append(&other);
assert_eq!(vec.len(), 5);
assert!(vec.indices(Sign::Plus).contains(&3));
assert!(vec.indices(Sign::Minus).contains(&4));
}
#[test]
fn test_insert_and_retain() {
let mut vec = svec![1, 2, 3, 2];
vec.insert(1, -1);
assert_eq!(vec.len(), 5);
assert_eq!(*vec.values(Sign::Minus).next().unwrap(), -1);
assert_eq!(vec.indices(Sign::Plus), &set![0, 2, 3, 4]);
assert_eq!(vec.indices(Sign::Minus), &set![1]);
vec.retain(|&x| x != -1);
assert_eq!(vec.len(), 4);
assert!(!vec.indices(Sign::Minus).contains(&1));
assert_eq!(vec.indices(Sign::Plus), &set![0, 1, 2, 3]);
assert_eq!(vec.indices(Sign::Minus), &set![]);
}
fn check_signvec_contents(vec: SignVec<i32>, expected_vals: &[i32]) {
assert_eq!(vec.vals, expected_vals);
}
#[test]
fn from_slice() {
let slice: &[i32] = &[1, -2, 3];
let sign_vec = SignVec::from(slice);
check_signvec_contents(sign_vec, slice);
}
#[test]
fn from_array() {
let array: &[i32; 3] = &[1, -2, 3];
let sign_vec = SignVec::from(array);
check_signvec_contents(sign_vec, array);
}
#[test]
fn from_owned_array() {
let array = [1, -2, 3]; let sign_vec = SignVec::from(array);
check_signvec_contents(sign_vec, &array);
}
#[test]
fn test_as_ref() {
let sign_vec = SignVec::from(&[1, -2, 3][..]);
assert_eq!(sign_vec.as_ref(), &vec![1, -2, 3]);
}
#[test]
fn test_default() {
let sign_vec: SignVec<i32> = SignVec::default();
assert!(sign_vec.vals.is_empty());
}
#[test]
fn test_extend_ref() {
let mut sign_vec = SignVec::default();
sign_vec.extend(&[1, -2, 3]);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_extend_owned() {
let mut sign_vec = SignVec::default();
sign_vec.extend(vec![1, -2, 3]);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_slice() {
let sign_vec = SignVec::from(&[1, -2, 3][..]);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_array_ref() {
let sign_vec = SignVec::from(&[1, -2, 3]);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_mut_slice() {
let sign_vec = SignVec::from(&mut [1, -2, 3][..]);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_mut_array_ref() {
let mut array = [1, -2, 3];
let sign_vec = SignVec::from(&mut array);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_vec_ref() {
let vec = vec![1, -2, 3];
let sign_vec = SignVec::from(&vec);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_vec() {
let vec = vec![1, -2, 3];
let sign_vec = SignVec::from(vec);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn test_from_array() {
let array = [1, -2, 3];
let sign_vec = SignVec::from(array);
assert_eq!(sign_vec.vals, vec![1, -2, 3]);
}
#[test]
fn from_iterator_owned() {
let items = vec![1, -1, 2, -2];
let sign_vec: SignVec<i32> = items.into_iter().collect();
assert_eq!(sign_vec.vals, vec![1, -1, 2, -2]);
}
#[test]
fn from_iterator_ref() {
let items = [1, -1, 2, -2];
let sign_vec: SignVec<i32> = items.iter().collect();
assert_eq!(sign_vec.vals, vec![1, -1, 2, -2]);
}
#[test]
fn into_iterator_owned() {
let sign_vec = SignVec::from(&[1, -1, 2, -2][..]);
let collected: Vec<i32> = sign_vec.into_iter().collect();
assert_eq!(collected, vec![1, -1, 2, -2]);
}
#[test]
fn into_iterator_ref() {
let sign_vec = SignVec::from(&[1, -1, 2, -2][..]);
let collected: Vec<&i32> = (&sign_vec).into_iter().collect();
assert_eq!(collected, vec![&1, &-1, &2, &-2]);
}
#[test]
fn into_iterator_mut_ref() {
let mut sign_vec = SignVec::from(&[1, -1, 2, -2][..]);
let mut collected: Vec<&mut i32> = (&mut sign_vec).into_iter().collect();
collected.iter_mut().for_each(|x| **x *= 2);
assert_eq!(sign_vec.vals, vec![2, -2, 4, -4]);
}
#[test]
fn index_test() {
let sv = SignVec::from(vec![1, -2, 3]);
assert_eq!(sv[0], 1);
assert_eq!(sv[1], -2);
assert_eq!(sv[2], 3);
}
#[test]
fn deref_test() {
let sv = SignVec::from(vec![1, -2, 3]);
let slice: &[i32] = &sv; assert_eq!(slice, &[1, -2, 3]);
}
#[test]
fn borrow_test() {
let sv = SignVec::from(vec![1, -2, 3]);
let slice: &[i32] = sv.borrow();
assert_eq!(slice, &[1, -2, 3]);
}
#[test]
fn hash_test() {
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
let sv = SignVec::from(vec![1, -2, 3]);
let mut hasher = DefaultHasher::new();
sv.hash(&mut hasher);
let hash = hasher.finish();
let mut hasher_vec = DefaultHasher::new();
vec![1, -2, 3].hash(&mut hasher_vec);
let hash_vec = hasher_vec.finish();
assert_eq!(hash, hash_vec);
}
#[test]
fn ord_partial_ord_test() {
let sv1 = SignVec::from(vec![1, 2, 3]);
let sv2 = SignVec::from(vec![1, 2, 4]);
assert!(sv1 < sv2);
assert!(sv2 > sv1);
}
#[test]
fn eq_partial_eq_test() {
let sv1 = SignVec::from(vec![1, 2, 3]);
let sv2 = SignVec::from(vec![1, 2, 3]);
let sv3 = SignVec::from(vec![1, 2, 4]);
assert_eq!(sv1, sv2);
assert_ne!(sv1, sv3);
}
#[test]
fn partial_eq_with_others_test() {
let sv = SignVec::from(vec![1, 2, 3]);
let slice: &[i32] = &[1, 2, 3];
assert_eq!(sv, slice);
let mut_slice: &mut [i32] = &mut [1, 2, 3];
assert_eq!(sv, mut_slice);
assert_eq!(sv, vec![1, 2, 3]); }
}