#[cfg(feature = "arrayvec")]
mod arrayvec_storage;
mod basic;
mod capped_storage;
mod clone;
mod detach;
mod disjoint;
mod drain;
mod get_at;
mod iter;
mod key;
mod key_at;
mod key_piece;
mod model;
mod overflow;
mod packed;
mod reset;
mod retain;
mod retire;
#[cfg(feature = "smallvec")]
mod smallvec_storage;
mod storage_contract;
mod try_insert;
mod unchecked;
mod vacant_entry;
mod zero_sized;
use crate::{Config, KeyPiece, Split};
use core::marker::PhantomData;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::vec::Vec;
#[allow(dead_code)]
pub(crate) struct Cfg<Idx, Gen>(PhantomData<(Idx, Gen)>);
impl<Idx: KeyPiece, Gen: KeyPiece> Config for Cfg<Idx, Gen> {
type Idx = Idx;
type Gen = Gen;
type Layout = Split;
type Storage<S> = Vec<S>;
}
#[derive(Clone)]
pub(crate) struct DropTracker {
state: Rc<RefCell<TrackerState>>,
}
struct TrackerState {
drops: HashMap<u32, u32>,
next_id: u32,
}
impl DropTracker {
pub(crate) fn new() -> Self {
Self {
state: Rc::new(RefCell::new(TrackerState {
drops: HashMap::new(),
next_id: 0,
})),
}
}
pub(crate) fn make_item(&self) -> DropItem {
let mut state = self.state.borrow_mut();
let id = state.next_id;
state.next_id += 1;
DropItem {
id,
state: self.state.clone(),
}
}
pub(crate) fn total_dropped(&self) -> usize {
self.state.borrow().drops.len()
}
pub(crate) fn total_made(&self) -> u32 {
self.state.borrow().next_id
}
pub(crate) fn assert_all_dropped_exactly_once(&self, n: u32) {
let state = self.state.borrow();
for id in 0..n {
let count = state.drops.get(&id).copied().unwrap_or(0);
assert_eq!(count, 1, "item {id} was dropped {count} times");
}
assert_eq!(state.drops.len(), n as usize);
}
pub(crate) fn assert_none_dropped(&self) {
let dropped = self.total_dropped();
assert_eq!(
dropped, 0,
"expected no drops, but {dropped} items were dropped"
);
}
}
pub(crate) struct DropItem {
id: u32,
state: Rc<RefCell<TrackerState>>,
}
impl Clone for DropItem {
fn clone(&self) -> Self {
let mut state = self.state.borrow_mut();
let id = state.next_id;
state.next_id += 1;
DropItem {
id,
state: self.state.clone(),
}
}
}
impl Drop for DropItem {
fn drop(&mut self) {
let mut state = self.state.borrow_mut();
let count = state.drops.entry(self.id).or_insert(0);
*count += 1;
assert!(*count <= 1, "item {} was dropped {} times", self.id, *count);
}
}
pub(crate) struct Bomb {
armed: bool,
_item: DropItem,
}
impl Bomb {
pub(crate) fn new(tracker: &DropTracker, armed: bool) -> Self {
Self {
armed,
_item: tracker.make_item(),
}
}
}
impl Drop for Bomb {
fn drop(&mut self) {
if self.armed && !std::thread::panicking() {
panic!("boom");
}
}
}