#![allow(dead_code)]
use std::collections::HashSet;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct IndexList {
order: Vec<usize>,
set: HashSet<usize>,
}
#[allow(dead_code)]
pub fn new_index_list() -> IndexList {
IndexList {
order: Vec::new(),
set: HashSet::new(),
}
}
#[allow(dead_code)]
pub fn il_push(list: &mut IndexList, idx: usize) -> bool {
if list.set.contains(&idx) {
return false;
}
list.order.push(idx);
list.set.insert(idx);
true
}
#[allow(dead_code)]
pub fn il_remove(list: &mut IndexList, idx: usize) -> bool {
if !list.set.remove(&idx) {
return false;
}
list.order.retain(|&x| x != idx);
true
}
#[allow(dead_code)]
pub fn il_contains(list: &IndexList, idx: usize) -> bool {
list.set.contains(&idx)
}
#[allow(dead_code)]
pub fn il_len(list: &IndexList) -> usize {
list.order.len()
}
#[allow(dead_code)]
pub fn il_is_empty(list: &IndexList) -> bool {
list.order.is_empty()
}
#[allow(dead_code)]
pub fn il_get(list: &IndexList, pos: usize) -> Option<usize> {
list.order.get(pos).copied()
}
#[allow(dead_code)]
pub fn il_clear(list: &mut IndexList) {
list.order.clear();
list.set.clear();
}
#[allow(dead_code)]
pub fn il_as_slice(list: &IndexList) -> &[usize] {
&list.order
}
#[allow(dead_code)]
pub fn il_merge(list: &mut IndexList, other: &IndexList) {
for &idx in &other.order {
il_push(list, idx);
}
}
#[allow(dead_code)]
pub fn il_retain<F: Fn(usize) -> bool>(list: &mut IndexList, f: F) {
let old = std::mem::take(&mut list.order);
list.set.clear();
for idx in old {
if f(idx) {
list.order.push(idx);
list.set.insert(idx);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_push_and_contains() {
let mut list = new_index_list();
assert!(il_push(&mut list, 3));
assert!(il_contains(&list, 3));
}
#[test]
fn test_no_duplicates() {
let mut list = new_index_list();
il_push(&mut list, 5);
assert!(!il_push(&mut list, 5));
assert_eq!(il_len(&list), 1);
}
#[test]
fn test_remove() {
let mut list = new_index_list();
il_push(&mut list, 7);
assert!(il_remove(&mut list, 7));
assert!(!il_contains(&list, 7));
}
#[test]
fn test_remove_nonexistent() {
let mut list = new_index_list();
assert!(!il_remove(&mut list, 99));
}
#[test]
fn test_order_preserved() {
let mut list = new_index_list();
il_push(&mut list, 10);
il_push(&mut list, 5);
il_push(&mut list, 20);
assert_eq!(il_as_slice(&list), &[10, 5, 20]);
}
#[test]
fn test_clear() {
let mut list = new_index_list();
il_push(&mut list, 1);
il_clear(&mut list);
assert!(il_is_empty(&list));
}
#[test]
fn test_merge() {
let mut a = new_index_list();
il_push(&mut a, 1);
let mut b = new_index_list();
il_push(&mut b, 2);
il_push(&mut b, 1);
il_merge(&mut a, &b);
assert_eq!(il_len(&a), 2);
}
#[test]
fn test_retain() {
let mut list = new_index_list();
for i in 0..6 {
il_push(&mut list, i);
}
il_retain(&mut list, |x| x % 2 == 0);
assert_eq!(il_as_slice(&list), &[0, 2, 4]);
}
#[test]
fn test_get() {
let mut list = new_index_list();
il_push(&mut list, 42);
assert_eq!(il_get(&list, 0), Some(42));
assert_eq!(il_get(&list, 1), None);
}
}