pub const trait CollectOptions
where
Self: Sized,
{
type Output;
fn collect_options(self) -> Self::Output;
}
impl<T> CollectOptions for Vec<Option<T>> {
type Output = Option<Vec<T>>;
fn collect_options(self) -> Self::Output {
self.into_iter().collect()
}
}
pub mod helper_functions_list;
use crate::{
extensions::lists::helper_functions_list::*,
math::{ConstZero, NumberWithMonotoneOps},
prelude::TryIntoPatch,
};
pub const trait ListPushOrReplaceOnMaxSize<T> {
fn push_or_replace_on_max_size(&mut self, max_size: usize, item: T);
}
pub const trait ListGetRegion<T: Copy> {
fn get_region(
&self,
vec_width: usize,
cutout_x: usize,
cutout_y: usize,
cutout_width: usize,
cutout_height: usize,
) -> Vec<T>;
}
pub const trait ListCombined<T: Clone + Sized> {
fn combined(&self, other: T) -> Vec<T>;
}
pub const trait ListAverage<T> {
fn average(&self) -> Option<T>;
}
pub const trait ListHasDuplicates<T: core::hash::Hash + Eq> {
fn has_duplicates(&self) -> bool;
}
pub const trait Index<T: core::cmp::PartialEq> {
fn find(&self, item: &T) -> Option<usize>;
}
impl<T: core::cmp::Eq> Index<T> for Vec<T> {
fn find(&self, item: &T) -> Option<usize> {
find_in_list(self, item)
}
}
pub const trait ListMisc<T> {
#[must_use]
#[allow(patterns_in_fns_without_body)]
fn sorted(mut self) -> Self;
#[must_use]
#[allow(patterns_in_fns_without_body)]
fn sorted_by<F>(mut self, compare: F) -> Self
where
F: FnMut(&T, &T) -> std::cmp::Ordering;
}
impl<T: std::cmp::Ord> ListMisc<T> for Vec<T> {
fn sorted(mut self) -> Self {
self.sort();
self
}
fn sorted_by<F>(mut self, compare: F) -> Self
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
self.sort_by(compare);
self
}
}
pub const trait ListGetNewItems<'a, T: core::cmp::PartialEq> {
fn get_new_items(&'a self, old: &'a [T]) -> Vec<&'a T>;
fn get_old_items(&'a self, new: &'a [T]) -> Vec<&'a T>;
}
pub const trait ListGetNewItemsCloned<T: core::cmp::PartialEq + Clone> {
fn get_new_items_cloned(&self, old: &[T]) -> Vec<T>;
fn get_old_items_cloned(&self, new: &[T]) -> Vec<T>;
}
impl<T> ListPushOrReplaceOnMaxSize<T> for Vec<T> {
fn push_or_replace_on_max_size(&mut self, max_size: usize, item: T) {
add_item_to_max_sized_list(self, max_size, item);
}
}
impl<T: core::cmp::Eq + core::hash::Hash> ListHasDuplicates<T> for Vec<T> {
fn has_duplicates(&self) -> bool {
has_duplicates(self)
}
}
impl<T: Copy> ListGetRegion<T> for Vec<T> {
fn get_region(
&self,
vec_width: usize,
cutout_x: usize,
cutout_y: usize,
cutout_width: usize,
cutout_height: usize,
) -> Self {
get_sub_vec_of_vec(
self,
vec_width,
cutout_x,
cutout_y,
cutout_width,
cutout_height,
)
}
}
impl<'a, T: core::cmp::PartialEq> ListGetNewItems<'a, T> for Vec<T> {
fn get_new_items(&'a self, old: &'a [T]) -> Vec<&'a T> {
get_difference_new(old, self)
}
fn get_old_items(&'a self, new: &'a [T]) -> Vec<&'a T> {
get_difference_new(self, new)
}
}
#[allow(clippy::use_self)] impl<T: core::cmp::PartialEq + Clone> ListGetNewItemsCloned<T> for Vec<T> {
fn get_new_items_cloned(&self, old: &[T]) -> Vec<T> {
get_difference_new_cloned(old, self)
}
fn get_old_items_cloned(&self, new: &[T]) -> Vec<T> {
get_difference_new_cloned(self, new)
}
}
impl<T: core::clone::Clone> ListCombined<T> for Vec<T> {
fn combined(&self, other: T) -> Self {
combined(self, other)
}
}
impl<T: ConstZero + Copy + PartialEq + NumberWithMonotoneOps> ListAverage<T>
for Vec<T>
where
usize: TryIntoPatch<T>,
{
fn average(&self) -> Option<T> {
average(self)
}
}
pub const trait ListLike<T, Idx>:
core::ops::Index<Idx> + core::ops::IndexMut<Idx> + ListLikeHelper<T, Idx>
{
fn push_mut(&mut self, value: T) -> &mut T;
fn try_remove(&mut self, index: Idx) -> Option<T>;
fn swap_values(&mut self, a: Idx, b: Idx);
fn len(&self) -> usize;
fn pop(&mut self) -> Option<T>;
fn insert_mut(&mut self, index: usize, value: T) -> &mut T;
fn try_replace(&mut self, index: usize, value: T) -> Option<T>;
fn try_reserve(
&mut self,
amount: usize,
) -> Result<(), std::collections::TryReserveError>;
fn find_position(&self, item: &T) -> Option<Idx>;
fn clear(&mut self);
}
pub const trait ListLikeHelper<T, Idx> {
fn remove(&mut self, index: Idx) -> T;
fn push(&mut self, value: T);
fn is_empty(&mut self) -> bool;
fn insert(&mut self, index: usize, value: T);
fn replace(&mut self, index: usize, value: T) -> T;
fn contains(&self, item: &T) -> bool;
fn reserve(&mut self, amount: usize);
}
impl<T: std::cmp::PartialEq> ListLike<T, usize> for Vec<T> {
fn push_mut(&mut self, value: T) -> &mut T {
self.push_mut(value)
}
fn try_remove(&mut self, index: usize) -> Option<T> {
vec_try_remove(self, index)
}
fn swap_values(&mut self, a: usize, b: usize) {
self.swap(a, b);
}
fn len(&self) -> usize {
self.len()
}
fn insert_mut(&mut self, index: usize, value: T) -> &mut T {
self.insert_mut(index, value)
}
fn pop(&mut self) -> Option<T> {
self.pop()
}
fn try_replace(&mut self, index: usize, value: T) -> Option<T> {
if index >= self.len() {
return None;
}
let mut value = value;
core::mem::swap(&mut self[index], &mut value);
Some(value)
}
fn find_position(&self, item: &T) -> Option<usize> {
self.iter().position(|x| (*x).eq(item))
}
fn try_reserve(
&mut self,
amount: usize,
) -> Result<(), std::collections::TryReserveError> {
self.try_reserve(amount)
}
fn clear(&mut self) {
self.clear();
}
}
impl<S: ListLike<T, Idx>, T, Idx> ListLikeHelper<T, Idx> for S {
fn remove(&mut self, index: Idx) -> T {
self.try_remove(index).unwrap()
}
fn push(&mut self, value: T) {
self.push_mut(value);
}
fn is_empty(&mut self) -> bool {
self.len() == 0
}
fn insert(&mut self, index: usize, value: T) {
self.insert_mut(index, value);
}
fn replace(&mut self, index: usize, value: T) -> T {
self.try_replace(index, value).unwrap()
}
fn contains(&self, item: &T) -> bool {
self.find_position(item).is_some()
}
fn reserve(&mut self, amount: usize) {
self.try_reserve(amount).unwrap();
}
}
mod sparse_vec;
pub use sparse_vec::*;
pub fn vec_try_remove<T>(list: &mut Vec<T>, index: usize) -> Option<T> {
let len = list.len();
if index >= len {
return None;
}
unsafe {
let ret;
{
let ptr = list.as_mut_ptr().add(index);
ret = core::ptr::read(ptr);
core::ptr::copy(ptr.add(1), ptr, len - index - 1);
}
list.set_len(len - 1);
Some(ret)
}
}