use core::ops::{BitAnd, BitOr, BitXor, Not};
use crate::sealed::Sealed;
pub trait Boolean: Sealed + Copy + Default + 'static {
const BOOL: bool;
fn new() -> Self;
fn as_bool(&self) -> bool {
Self::BOOL
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)]
pub struct False;
impl False {
#[inline(always)]
pub const fn new() -> Self {
False
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)]
pub struct True;
impl True {
#[inline(always)]
pub const fn new() -> Self {
True
}
}
impl Sealed for False {}
impl Sealed for True {}
impl Boolean for False {
const BOOL: bool = false;
#[inline(always)]
fn new() -> Self {
Self
}
}
impl Boolean for True {
const BOOL: bool = true;
#[inline(always)]
fn new() -> Self {
Self
}
}
impl Not for False {
type Output = True;
#[inline(always)]
fn not(self) -> Self::Output {
True
}
}
impl Not for True {
type Output = False;
#[inline(always)]
fn not(self) -> Self::Output {
False
}
}
impl<Rhs: Boolean> BitAnd<Rhs> for False {
type Output = Self;
#[inline(always)]
fn bitand(self, _: Rhs) -> Self::Output {
Self
}
}
impl<Rhs: Boolean> BitAnd<Rhs> for True {
type Output = Rhs;
#[inline(always)]
fn bitand(self, rhs: Rhs) -> Self::Output {
rhs
}
}
impl<Rhs: Boolean> BitOr<Rhs> for False {
type Output = Rhs;
#[inline(always)]
fn bitor(self, rhs: Rhs) -> Self::Output {
rhs
}
}
impl<Rhs: Boolean> BitOr<Rhs> for True {
type Output = Self;
#[inline(always)]
fn bitor(self, _: Rhs) -> Self::Output {
self
}
}
impl BitXor<False> for False {
type Output = False;
#[inline(always)]
fn bitxor(self, _: False) -> Self::Output {
False
}
}
impl BitXor<False> for True {
type Output = True;
#[inline(always)]
fn bitxor(self, _: False) -> Self::Output {
True
}
}
impl BitXor<True> for False {
type Output = True;
#[inline(always)]
fn bitxor(self, _: True) -> Self::Output {
True
}
}
impl BitXor<True> for True {
type Output = False;
#[inline(always)]
fn bitxor(self, _: True) -> Self::Output {
False
}
}
impl<T: Boolean> From<T> for bool {
fn from(b: T) -> Self {
b.as_bool()
}
}