use std::ops::{Index, IndexMut};
use rustc_hash::FxHashMap;
use serde::Deserialize;
use serde::Serialize;
use super::CycleId;
use super::CycleIndex;
use super::QuditCycle;
#[derive(Clone, Serialize, Deserialize)]
pub struct CycleList {
cycles: Vec<QuditCycle>,
id_to_index: FxHashMap<CycleId, CycleIndex>,
id_counter: u64,
}
impl CycleList {
pub fn with_capacity(capacity: usize) -> CycleList {
CycleList {
cycles: Vec::with_capacity(capacity),
id_to_index: FxHashMap::default(),
id_counter: 0,
}
}
fn get_new_id(&mut self) -> CycleId {
let out = self.id_counter;
if out >= u64::MAX - 1 {
panic!("Cycle identifier overflow.");
}
self.id_counter += 1;
CycleId(out)
}
pub fn push(&mut self) -> CycleIndex {
let new_id = self.get_new_id();
self.id_to_index.insert(new_id, self.cycles.len().into());
self.cycles.push(QuditCycle::new(new_id));
(self.cycles.len() - 1).into()
}
pub fn len(&self) -> usize {
self.cycles.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn id_to_index(&self, id: CycleId) -> Option<CycleIndex> {
self.id_to_index.get(&id).copied()
}
#[inline]
pub fn index_to_id(&self, idx: CycleIndex) -> CycleId {
self.cycles[usize::from(idx)].id()
}
pub fn iter(&self) -> <&Vec<QuditCycle> as IntoIterator>::IntoIter {
self.cycles.iter()
}
pub fn remove_index(&mut self, idx: CycleIndex) {
let idx = usize::from(idx);
if idx >= self.len() {
panic!("Index out of bounds."); }
let id = self.cycles[idx].id();
self.id_to_index.remove(&id);
self.cycles.remove(idx);
}
pub fn remove_id(&mut self, id: CycleId) {
match self.id_to_index(id) {
None => {} Some(idx) => self.remove_index(idx),
}
}
pub fn get_from_id(&self, id: CycleId) -> Option<&QuditCycle> {
self.id_to_index(id).map(|idx| &self.cycles[idx.0 as usize])
}
pub fn get_mut_from_id(&mut self, id: CycleId) -> Option<&mut QuditCycle> {
self.id_to_index(id)
.map(|idx| &mut self.cycles[idx.0 as usize])
}
pub fn is_id(&self, id: CycleId) -> bool {
self.id_to_index.contains_key(&id)
}
}
impl Index<usize> for CycleList {
type Output = QuditCycle;
fn index(&self, idx: usize) -> &Self::Output {
&self.cycles[idx]
}
}
impl IndexMut<usize> for CycleList {
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
&mut self.cycles[idx]
}
}
impl Index<CycleIndex> for CycleList {
type Output = QuditCycle;
fn index(&self, idx: CycleIndex) -> &Self::Output {
&self.cycles[usize::from(idx)]
}
}
impl IndexMut<CycleIndex> for CycleList {
fn index_mut(&mut self, idx: CycleIndex) -> &mut Self::Output {
&mut self.cycles[usize::from(idx)]
}
}
impl Index<CycleId> for CycleList {
type Output = QuditCycle;
fn index(&self, id: CycleId) -> &Self::Output {
let idx = self.id_to_index(id).expect("Cycle id does not exist.");
&self.cycles[usize::from(idx)]
}
}
impl IndexMut<CycleId> for CycleList {
fn index_mut(&mut self, id: CycleId) -> &mut Self::Output {
let idx = self.id_to_index(id).expect("Cycle id does not exist.");
&mut self.cycles[usize::from(idx)]
}
}
impl std::fmt::Debug for CycleList {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut debug_struct_fmt = fmt.debug_struct("CycleList");
for (i, cycle) in self.cycles.iter().enumerate() {
debug_struct_fmt.field(&format!("Cycle {}", i), &cycle);
}
debug_struct_fmt.finish()
}
}
impl<'a> IntoIterator for &'a CycleList {
type IntoIter = <&'a Vec<QuditCycle> as IntoIterator>::IntoIter;
type Item = &'a QuditCycle;
fn into_iter(self) -> Self::IntoIter {
self.cycles.iter()
}
}