use std::hash::Hash;
use std::ops::Index;
use fxhash::FxBuildHasher;
use indexmap::IndexSet;
use crate::VecX;
pub struct IndexedVecXs<T, const N: usize>
where T: PartialEq + Eq + Hash + Sized + Send
{
pub values: IndexSet<VecX<T, N>, FxBuildHasher>,
pub indices: Vec<usize>,
}
impl<T, const N: usize> IndexedVecXs<T, N>
where T: PartialEq + Eq + Hash + Sized + Send
{
pub fn new(
values: IndexSet<VecX<T, N>, FxBuildHasher>,
indices: Vec<usize>) -> Self {
Self {
values,
indices,
}
}
pub fn empty() -> Self {
Self {
values: IndexSet::<VecX<T, N>, FxBuildHasher>::default(),
indices: Vec::new(),
}
}
pub fn iter(&self) -> Vec<&VecX<T, N>> {
self.indices.iter().map(|i| self.values.get_index(*i).unwrap()).collect::<Vec<_>>()
}
pub fn from_vec(vec: Vec<VecX<T, N>>) -> Self {
let mut values = IndexSet::<VecX<T, N>, FxBuildHasher>::with_capacity_and_hasher(vec.len(), FxBuildHasher::default());
let indices = vec.into_iter().map(|value| values.insert_full(value).0).collect();
Self {
values,
indices,
}
}
pub fn to_ref_vec(&self) -> Vec<&VecX<T, N>> {
self.indices.iter().map(|i| self.values.get_index(*i).unwrap()).collect::<Vec<_>>()
}
pub fn insert(&mut self, value: VecX<T, N>) -> bool {
let (index, is_new) = self.values.insert_full(value);
self.indices.push(index);
is_new
}
}
impl<T, const N: usize> IndexedVecXs<T, N>
where T: PartialEq + Eq + Hash + Copy + Sized + Send
{
pub fn to_vec(self) -> Vec<VecX<T, N>> {
self.indices.into_iter().map(|i| *self.values.get_index(i).unwrap()).collect::<Vec<_>>()
}
}
impl<T: PartialEq + Eq + Hash, const N: usize> Index<usize> for IndexedVecXs<T, N>
where T: PartialEq + Eq + Hash + Sized + Send
{
type Output = VecX<T, N>;
fn index(&self, index: usize) -> &Self::Output {
let i = self.indices.get(index).unwrap();
self.values.get_index(*i).unwrap()
}
}
pub struct IndexedVecXIter<'a, T, const N: usize>
where T: PartialEq + Eq + Hash + Sized + Send
{
collection: &'a IndexedVecXs<T, N>,
current_index: usize,
}
impl<'a, T, const N: usize> Iterator for IndexedVecXIter<'a, T, N>
where T: PartialEq + Eq + Hash + Sized + Send
{
type Item = &'a VecX<T, N>;
fn next(&mut self) -> Option<Self::Item> {
if self.current_index < self.collection.indices.len() {
self.current_index += 1;
Some(&self.collection[self.current_index])
} else {
None
}
}
}