#![doc = include_str!("../README.md")]
#![cfg_attr(not(test), no_std)]
use core::{hint::unreachable_unchecked, marker::PhantomData};
use cismute::Cismutable;
macro_rules! cisunreachable {
() => {
unreachable!("cismute live-witness used in code path where types were not actually the same/cismutable")
};
}
pub struct LiveWitness<Ty, Is>(PhantomData<Ty>, PhantomData<Is>);
impl<U, T> Clone for LiveWitness<U, T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<U, T> Copy for LiveWitness<U, T> {}
impl<Ty, Is> LiveWitness<Ty, Is> {
#[inline(always)]
pub const fn inverse(self) -> LiveWitness<Is, Ty> {
LiveWitness::only_executed_if_same()
}
#[inline(always)]
pub const fn only_executed_if_same() -> Self {
Self(PhantomData, PhantomData)
}
#[inline(always)]
pub unsafe fn value_unchecked<'a, RefTy, RefIs>(&self, from: RefTy) -> RefIs
where
Ty: 'static,
Is: 'static,
RefTy: Cismutable<'a, Ty, Is, RefIs>,
{
match cismute::value(from) {
Ok(v) => v,
Err(_) => unreachable_unchecked(),
}
}
#[inline(always)]
pub fn value<'a, RefTy, RefIs>(&self, from: RefTy) -> RefIs
where
Ty: 'static,
Is: 'static,
RefTy: Cismutable<'a, Ty, Is, RefIs>,
{
match cismute::value(from) {
Ok(v) => v,
Err(_) => {
cisunreachable!()
}
}
}
#[inline(always)]
pub unsafe fn owned_unchecked(&self, from: Ty) -> Is
where
Ty: 'static,
Is: 'static,
{
match cismute::owned(from) {
Ok(v) => v,
Err(_) => unreachable_unchecked(),
}
}
#[inline(always)]
pub fn owned(&self, from: Ty) -> Is
where
Ty: 'static,
Is: 'static,
{
match cismute::owned(from) {
Ok(v) => v,
Err(_) => cisunreachable!(),
}
}
#[inline(always)]
pub unsafe fn reference_unchecked<'a>(&self, from: &'a Ty) -> &'a Is
where
Ty: 'static,
Is: 'static,
&'a Ty: Cismutable<'a, Ty, Is, &'a Is>,
{
match cismute::reference(from) {
Ok(v) => v,
Err(_) => unreachable_unchecked(),
}
}
#[inline(always)]
pub fn reference<'a>(&self, from: &'a Ty) -> &'a Is
where
Ty: 'static,
Is: 'static,
&'a Ty: Cismutable<'a, Ty, Is, &'a Is>,
{
match cismute::reference(from) {
Ok(v) => v,
Err(_) => cisunreachable!(),
}
}
#[inline(always)]
pub unsafe fn mutable_unchecked<'a>(&self, from: &'a mut Ty) -> &'a mut Is
where
Ty: 'static,
Is: 'static,
&'a mut Ty: Cismutable<'a, Ty, Is, &'a mut Is>,
{
match cismute::mutable(from) {
Ok(v) => v,
Err(_) => unreachable_unchecked(),
}
}
#[inline(always)]
pub fn mutable<'a>(&self, from: &'a mut Ty) -> &'a mut Is
where
Ty: 'static,
Is: 'static,
&'a mut Ty: Cismutable<'a, Ty, Is, &'a mut Is>,
{
match cismute::mutable(from) {
Ok(v) => v,
Err(_) => cisunreachable!(),
}
}
}