use std::collections::HashSet;
use std::sync::{Arc, Mutex, RwLock};
pub trait GetSizeTracker {
fn track<A>(&mut self, addr: *const A) -> bool;
}
impl<T: GetSizeTracker> GetSizeTracker for &mut T {
fn track<A>(&mut self, addr: *const A) -> bool {
GetSizeTracker::track(*self, addr)
}
}
impl<T: GetSizeTracker> GetSizeTracker for Box<T> {
fn track<A>(&mut self, addr: *const A) -> bool {
GetSizeTracker::track(&mut **self, addr)
}
}
impl<T: GetSizeTracker> GetSizeTracker for Mutex<T> {
fn track<A>(&mut self, addr: *const A) -> bool {
let tracker = self
.get_mut()
.unwrap_or_else(std::sync::PoisonError::into_inner);
GetSizeTracker::track(&mut *tracker, addr)
}
}
impl<T: GetSizeTracker> GetSizeTracker for RwLock<T> {
fn track<A>(&mut self, addr: *const A) -> bool {
let mut tracker = self
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
GetSizeTracker::track(&mut *tracker, addr)
}
}
impl<T: GetSizeTracker> GetSizeTracker for Arc<Mutex<T>> {
fn track<A>(&mut self, addr: *const A) -> bool {
let mut tracker = self
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
GetSizeTracker::track(&mut *tracker, addr)
}
}
impl<T: GetSizeTracker> GetSizeTracker for Arc<RwLock<T>> {
fn track<A>(&mut self, addr: *const A) -> bool {
let mut tracker = self
.write()
.unwrap_or_else(std::sync::PoisonError::into_inner);
GetSizeTracker::track(&mut *tracker, addr)
}
}
#[derive(Debug, Default)]
pub struct StandardTracker {
inner: HashSet<usize>,
}
impl StandardTracker {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn clear(&mut self) {
self.inner.clear();
}
}
impl GetSizeTracker for StandardTracker {
fn track<A>(&mut self, addr: *const A) -> bool {
self.inner.insert(addr.addr())
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NoTracker {
answer: bool,
}
impl NoTracker {
#[must_use]
pub const fn new(answer: bool) -> Self {
Self { answer }
}
#[must_use]
pub const fn answer(&self) -> bool {
self.answer
}
pub const fn set_answer(&mut self, answer: bool) {
self.answer = answer;
}
}
impl GetSizeTracker for NoTracker {
fn track<A>(&mut self, _addr: *const A) -> bool {
self.answer
}
}