#![deny(missing_docs)]
use num_traits::identities::one;
use std::marker::PhantomData;
pub mod counter;
use counter::Counter;
pub use type_census_derive::Tabulate;
#[repr(transparent)]
pub struct Instance<T>
where
T: Tabulate,
{
_tabulated: PhantomData<T>,
}
impl<T> Instance<T>
where
T: Tabulate,
{
#[inline(always)]
pub fn new() -> Self {
T::counter().add_assign(one());
Instance {
_tabulated: PhantomData,
}
}
}
impl<T> std::fmt::Debug for Instance<T>
where
T: Tabulate,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(std::any::type_name::<Self>()).finish()
}
}
impl<T> Default for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn default() -> Self {
Self::new()
}
}
impl<T> Clone for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn clone(&self) -> Self {
Self::new()
}
}
impl<T> Drop for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn drop(&mut self) {
T::counter().sub_assign(one());
}
}
impl<T> std::hash::Hash for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
}
impl<T> Ord for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn cmp(&self, _: &Self) -> std::cmp::Ordering {
std::cmp::Ordering::Equal
}
}
impl<T> PartialOrd for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn partial_cmp(&self, _: &Self) -> Option<std::cmp::Ordering> {
Some(std::cmp::Ordering::Equal)
}
}
impl<T> Eq for Instance<T> where T: Tabulate {}
impl<T> PartialEq for Instance<T>
where
T: Tabulate,
{
#[inline(always)]
fn eq(&self, _: &Self) -> bool {
true
}
}
pub trait Tabulate: Sized {
type Counter: Counter;
fn counter() -> &'static Self::Counter;
fn instances() -> <Self::Counter as Counter>::Primitive {
Self::counter().fetch()
}
}