#![doc = include_str!("../README.md")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
mod atomic;
mod internal;
#[cfg(test)]
mod test;
use std::ops::{BitAnd, BitAndAssign};
pub struct Condition(Token);
impl Condition {
pub fn new() -> Self {
Self(internal::ThreadAllocator::with(internal::source))
}
pub fn token(&self) -> Token {
self.0
}
}
impl Drop for Condition {
fn drop(&mut self) {
let Token { block, ext_id } = self.0;
internal::ThreadAllocator::with(|alloc| {
internal::invalidate_source(alloc, block.as_ref(), ext_id)
});
}
}
impl Default for Condition {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for Condition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Condition")
.field(&internal::TokenId::from(self.0.ext_id).index())
.finish()
}
}
#[derive(Clone, Copy)]
pub struct Token {
block: internal::TokenBlockRef<'static>,
ext_id: internal::ExtTokenId,
}
impl Token {
pub fn always() -> Self {
internal::always()
}
pub fn never() -> Self {
internal::never()
}
pub fn is_valid(&self) -> bool {
internal::is_valid(*self)
}
}
impl Default for Token {
fn default() -> Self {
Self::always()
}
}
impl BitAnd for Token {
type Output = Token;
fn bitand(self, rhs: Self) -> Token {
internal::ThreadAllocator::with(|alloc| internal::dependent(alloc, self, rhs))
}
}
impl BitAndAssign for Token {
fn bitand_assign(&mut self, rhs: Self) {
*self = *self & rhs;
}
}
impl std::fmt::Debug for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut d = f.debug_tuple("Token");
let mut deps = Vec::new();
if internal::dependencies(*self, |dep| {
deps.push(internal::TokenId::from(dep.ext_id).index())
}) {
d.field(&deps);
} else {
d.field(&format_args!("<invalid>"));
}
d.finish()
}
}