use crate::std_core::{fmt, hash, marker::PhantomData, ops, ptr::NonNull};
use super::{Token, Unsync};
pub struct SingletonToken<Tag: ?Sized, Variant = SyncVariant>(
PhantomData<(Invariant<Tag>, Variant)>,
);
pub type UnsyncSingletonToken<Tag> = SingletonToken<Tag, UnsyncVariant>;
#[doc(hidden)]
pub struct SyncVariant(());
#[doc(hidden)]
pub struct UnsyncVariant(std::cell::Cell<()>);
#[doc(hidden)]
pub trait SingletonTokenVariant: private::Sealed {}
impl SingletonTokenVariant for SyncVariant {}
impl SingletonTokenVariant for UnsyncVariant {}
mod private {
pub trait Sealed {}
impl Sealed for super::SyncVariant {}
impl Sealed for super::UnsyncVariant {}
}
struct Invariant<Tag: ?Sized>(fn(&Tag) -> &Tag);
impl<Tag: ?Sized, Variant: SingletonTokenVariant> fmt::Debug for SingletonToken<Tag, Variant> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SingletonToken")
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> PartialEq for SingletonToken<Tag, Variant> {
#[inline]
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> Eq for SingletonToken<Tag, Variant> {}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> hash::Hash for SingletonToken<Tag, Variant> {
#[inline]
fn hash<H: hash::Hasher>(&self, _: &mut H) {}
}
impl<Tag: ?Sized, Variant> SingletonToken<Tag, Variant> {
#[inline(always)]
pub const unsafe fn new_unchecked() -> Self {
Self(PhantomData)
}
#[inline(always)]
pub fn id(&self) -> SingletonTokenId<Tag> {
SingletonTokenId(PhantomData)
}
#[inline]
pub fn borrow(&self) -> SingletonTokenRef<'_, Tag, Variant> {
SingletonTokenRef(PhantomData)
}
#[inline]
pub fn borrow_mut(&mut self) -> SingletonTokenRefMut<'_, Tag, Variant> {
SingletonTokenRefMut(PhantomData)
}
}
impl<Tag: ?Sized> UnsyncSingletonToken<Tag> {
#[inline]
pub fn borrow_sync(&self) -> SingletonTokenRef<'_, Tag> {
SingletonTokenRef(PhantomData)
}
#[inline]
pub fn borrow_sync_mut(&mut self) -> SingletonTokenRefMut<'_, Tag> {
SingletonTokenRefMut(PhantomData)
}
}
impl<Tag: ?Sized> SingletonToken<Tag> {
#[inline]
pub fn borrow_unsync_mut(&mut self) -> UnsyncSingletonTokenRefMut<'_, Tag> {
SingletonTokenRefMut(PhantomData)
}
}
impl<Tag: ?Sized> SingletonToken<Tag> {
#[inline]
pub const fn into_unsync(self) -> UnsyncSingletonToken<Tag> {
SingletonToken(PhantomData)
}
}
impl<Tag: ?Sized> UnsyncSingletonToken<Tag> {
#[inline]
pub const fn into_sync(self) -> SingletonToken<Tag> {
SingletonToken(PhantomData)
}
}
unsafe impl<Tag: ?Sized, Variant: SingletonTokenVariant> Token<SingletonTokenId<Tag>>
for SingletonToken<Tag, Variant>
{
#[inline(always)]
fn eq_id(&self, _: &SingletonTokenId<Tag>) -> bool {
true
}
}
unsafe impl<Tag: ?Sized> Unsync for UnsyncSingletonToken<Tag> {}
pub struct SingletonTokenRef<'a, Tag: ?Sized, Variant = SyncVariant>(
PhantomData<&'a SingletonToken<Tag, Variant>>,
);
pub type UnsyncSingletonTokenRef<'a, Tag> = SingletonTokenRef<'a, Tag, UnsyncVariant>;
impl<Tag: ?Sized, Variant: SingletonTokenVariant> fmt::Debug
for SingletonTokenRef<'_, Tag, Variant>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SingletonTokenRef")
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> PartialEq
for SingletonTokenRef<'_, Tag, Variant>
{
#[inline]
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> Eq for SingletonTokenRef<'_, Tag, Variant> {}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> hash::Hash
for SingletonTokenRef<'_, Tag, Variant>
{
#[inline]
fn hash<H: hash::Hasher>(&self, _: &mut H) {}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> ops::Deref
for SingletonTokenRef<'_, Tag, Variant>
{
type Target = SingletonToken<Tag, Variant>;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&SingletonToken(PhantomData)
}
}
pub struct SingletonTokenRefMut<'a, Tag: ?Sized, Variant = SyncVariant>(
PhantomData<&'a mut SingletonToken<Tag, Variant>>,
);
pub type UnsyncSingletonTokenRefMut<'a, Tag> = SingletonTokenRefMut<'a, Tag, UnsyncVariant>;
impl<Tag: ?Sized, Variant: SingletonTokenVariant> fmt::Debug
for SingletonTokenRefMut<'_, Tag, Variant>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SingletonTokenRefMut")
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> PartialEq
for SingletonTokenRefMut<'_, Tag, Variant>
{
#[inline]
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> Eq for SingletonTokenRefMut<'_, Tag, Variant> {}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> hash::Hash
for SingletonTokenRefMut<'_, Tag, Variant>
{
#[inline]
fn hash<H: hash::Hasher>(&self, _: &mut H) {}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> ops::Deref
for SingletonTokenRefMut<'_, Tag, Variant>
{
type Target = SingletonToken<Tag>;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&SingletonToken(PhantomData)
}
}
impl<Tag: ?Sized, Variant: SingletonTokenVariant> ops::DerefMut
for SingletonTokenRefMut<'_, Tag, Variant>
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *NonNull::dangling().as_ptr() }
}
}
pub struct SingletonTokenId<Tag: ?Sized>(PhantomData<Invariant<Tag>>);
impl<Tag: ?Sized> SingletonTokenId<Tag> {
#[inline]
pub const fn new() -> Self {
Self(PhantomData)
}
}
impl<Tag: ?Sized> Default for SingletonTokenId<Tag> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<Tag: ?Sized> fmt::Debug for SingletonTokenId<Tag> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SingletonTokenId")
}
}
impl<Tag: ?Sized> Clone for SingletonTokenId<Tag> {
#[inline]
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<Tag: ?Sized> Copy for SingletonTokenId<Tag> {}
impl<Tag: ?Sized> PartialEq for SingletonTokenId<Tag> {
#[inline]
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<Tag: ?Sized> Eq for SingletonTokenId<Tag> {}
impl<Tag: ?Sized> hash::Hash for SingletonTokenId<Tag> {
#[inline]
fn hash<H: hash::Hasher>(&self, _: &mut H) {}
}