use std::ops::BitOr;
use crate::component::{self, Component};
#[cfg(components_64)]
pub static MAX_COMPONENTS: usize = 64;
#[cfg(components_128)]
pub static MAX_COMPONENTS: usize = 128;
#[cfg(components_256)]
pub static MAX_COMPONENTS: usize = 256;
#[cfg(components_512)]
pub static MAX_COMPONENTS: usize = 512;
#[cfg(components_1024)]
pub static MAX_COMPONENTS: usize = 1024;
#[cfg(components_2048)]
pub static MAX_COMPONENTS: usize = 2048;
#[cfg(components_4096)]
pub static MAX_COMPONENTS: usize = 4096;
#[cfg(components_64)]
mod mask {
pub type MaskType = u64;
pub struct NextMask{
next: u64,
total_components: u8,
}
impl NextMask {
pub fn new() -> NextMask {
NextMask{
next: 1,
total_components: 0,
}
}
#[inline]
pub fn next(&mut self) -> MaskType{
self.total_components += 1;
if self.total_components > super::MAX_COMPONENTS as u8 {
panic!("Trying to register more than {} components, please use the bigint feature in your cargo dependency", super::MAX_COMPONENTS);
}
let ret = self.next;
self.next *= 2;
ret
}
pub fn get(&self) -> MaskType {
self.next
}
}
pub const fn zero() -> MaskType{
0
}
pub const fn one() -> MaskType{
1
}
pub const fn two() -> MaskType{
2
}
}
#[cfg(components_bigint)]
mod mask{
#[cfg(components_128)]
pub type MaskType = numext_fixed_uint::U128;
#[cfg(components_256)]
pub type MaskType = numext_fixed_uint::U256;
#[cfg(components_512)]
pub type MaskType = numext_fixed_uint::U512;
#[cfg(components_1024)]
pub type MaskType = numext_fixed_uint::U1024;
#[cfg(components_2048)]
pub type MaskType = numext_fixed_uint::U2048;
#[cfg(components_4096)]
pub type MaskType = numext_fixed_uint::U4096;
pub struct NextMask{
next: MaskType,
total_components: u16,
}
impl NextMask {
pub fn new() -> NextMask {
NextMask{
next: MaskType::from(1u8),
total_components: 0,
}
}
#[inline]
pub fn next(&mut self) -> MaskType{
self.total_components += 1;
if self.total_components > super::MAX_COMPONENTS as u16 {
panic!("Trying to register more than {} components, please use a larger number of components feature in your cargo dependency", super::MAX_COMPONENTS);
}
let ret = self.next.clone();
self.next *= MaskType::from(2u8);
ret
}
pub fn get(&self) -> MaskType {
self.next.clone()
}
}
pub const fn zero() -> MaskType{
MaskType::zero()
}
pub const fn one() -> MaskType{
MaskType::one()
}
pub fn two() -> MaskType{
MaskType::from(2u32)
}
}
impl Default for NextMask{
fn default() -> NextMask {
NextMask::new()
}
}
pub use self::mask::{MaskType, NextMask, zero, one, two};
use std::ops::Not;
#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
pub enum Bitmask{
All,
Has(MaskType),
Not(MaskType),
Or(MaskType),
Option(MaskType),
HasNot(MaskType, MaskType),
HasOr(MaskType, MaskType),
NotOr(MaskType, MaskType),
HasOption(MaskType, MaskType),
OrOption(MaskType, MaskType),
NotOption(MaskType, MaskType),
HasNotOr(MaskType, MaskType, MaskType),
HasNotOption(MaskType, MaskType, MaskType),
HasOrOption(MaskType, MaskType, MaskType),
NotOrOption(MaskType, MaskType, MaskType),
HasNotOrOption(MaskType, MaskType, MaskType, MaskType),
Refs(Vec<(component::Id, Bitmask)>),
OtherAndRefs(Box<Bitmask>, Vec<(component::Id, Bitmask)>),
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Check{
Yes,
No,
Refs(Vec<(component::Id, Bitmask)>),
}
impl<'a> From<bool> for Check{
fn from(b: bool) -> Check{
if b { Check::Yes } else { Check::No }
}
}
impl Bitmask{
#[inline]
pub fn all() -> Bitmask {
Bitmask::All
}
#[inline]
pub fn option(option: MaskType) -> Bitmask {
Bitmask::Option(option)
}
#[inline]
pub fn has(has: MaskType) -> Bitmask {
Bitmask::Has(has)
}
#[inline]
pub fn not(not: MaskType) -> Bitmask {
Bitmask::Not(not)
}
#[inline]
pub fn has_not(has: MaskType, not: MaskType) -> Bitmask {
Bitmask::HasNot(has, not)
}
#[inline]
pub fn or(or: MaskType) -> Bitmask {
Bitmask::Or(or)
}
pub fn reference<C: Component>(bitmask: Bitmask) -> Bitmask {
Bitmask::Refs(vec![(C::id(), bitmask)])
}
pub fn components(&self) -> MaskType {
match self {
Bitmask::HasNot(has, not) => has | not,
Bitmask::Has(has) => has.clone(),
Bitmask::Not(not) => not.clone(),
Bitmask::Or(or) => or.clone(),
Bitmask::Option(option) => option.clone(),
Bitmask::HasOr(has, or) => has | or,
Bitmask::NotOr(not, or) => not | or,
Bitmask::HasOption(has, option) => has | option,
Bitmask::OrOption(or, option) => or | option,
Bitmask::NotOption(not, option) => not | option,
Bitmask::HasNotOr(has, not, or) => has | not | or,
Bitmask::HasNotOption(has, not, option) => has | not | option,
Bitmask::HasOrOption(has, or, option) => has | or | option,
Bitmask::NotOrOption(not, or, option) => not | or | option,
Bitmask::HasNotOrOption(has, not, or, option) => has | not | or | option,
Bitmask::All => mask::zero(),
Bitmask::Refs(_refs) => mask::zero(),
Bitmask::OtherAndRefs(other, _refs) =>
other.components()
}
}
#[inline]
pub fn check(&self, mask: MaskType) -> Check {
match self {
Bitmask::HasNot(has, not)
| Bitmask::HasNotOption(has, not, _) =>
(mask.clone() & has.clone() == *has
&& (mask.clone() ^ (not.clone().not())) & not.clone() == mask::zero()).into(),
Bitmask::Has(has) | Bitmask::HasOption(has, _) =>
(mask.clone() & has.clone() == *has).into(),
Bitmask::Not(not) | Bitmask::NotOption(not, _) =>
((mask.clone() ^ (not.clone().not())) & not.clone() == mask::zero()).into(),
Bitmask::Or(or) | Bitmask::OrOption(or, _) =>
(mask.clone() & or.clone() != mask::zero()).into(),
Bitmask::HasOr(has, or)
| Bitmask::HasOrOption(has, or, _) =>
(mask.clone() & has.clone() == *has
&& mask.clone() & or.clone() != mask::zero()).into(),
Bitmask::NotOr(not, or)
| Bitmask::NotOrOption(not, or, _) =>
((mask.clone() ^ (not.clone().not())) & not.clone() == mask::zero()
&& mask.clone() & or.clone() != mask::zero()).into(),
Bitmask::HasNotOr(has, not, or)
| Bitmask::HasNotOrOption(has, not, or, _) =>
((mask.clone() & has.clone() == *has)
&& ((mask.clone() ^ (not.clone().not())) & not.clone() == mask::zero())
&& (mask.clone() & or.clone() != mask::zero())).into(),
Bitmask::All | Bitmask::Option(_) => Check::Yes,
Bitmask::Refs(refs) => Check::Refs(refs.clone()),
Bitmask::OtherAndRefs(other, refs) => match other.check(mask) {
Check::Yes => Check::Refs(refs.clone()),
Check::No => Check::No,
Check::Refs(more_refs) => {
let mut refs = refs.clone();
refs.extend_from_slice(&more_refs);
Check::Refs(refs)
}
}
}
}
}
impl BitOr for Bitmask{
type Output = Bitmask;
#[inline]
fn bitor(self, rhs: Bitmask) -> Bitmask {
use Bitmask::*;
match (self, rhs){
(Has(has), Has(rhs)) => Has(has | rhs),
(Has(has), Not(rhs)) => HasNot(has, rhs),
(Has(has), HasNot(rhs, rhs_not)) => HasNot(has | rhs, rhs_not),
(Has(has), Or(rhs)) => HasOr(has, rhs),
(Has(has), HasOr(rhs, rhs_or)) => HasOr(has | rhs, rhs_or),
(Has(has), NotOr(rhs_not, rhs_or)) => HasNotOr(has, rhs_not, rhs_or),
(Has(has), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(has | rhs, rhs_not, rhs_or),
(Has(has), Option(option)) => HasOption(has, option),
(Has(has), HasOption(rhs_has, rhs_option)) => HasOption(has | rhs_has, rhs_option),
(Has(has), NotOption(rhs_not, rhs_option)) => HasNotOption(has, rhs_not, rhs_option),
(Has(has), OrOption(rhs_or, rhs_option)) => HasOrOption(has, rhs_or, rhs_option),
(Has(has), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(has | rhs_has, rhs_not, rhs_option),
(Has(has), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(has | rhs_has, rhs_or, rhs_option),
(Has(has), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, rhs_not, rhs_or, rhs_option),
(Has(has), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, rhs_or, rhs_option),
(Has(has), All) => Has(has),
(Not(not), Not(rhs)) => Not(not | rhs),
(Not(not), HasNot(rhs, rhs_not)) => HasNot(rhs, not | rhs_not),
(Not(not), Or(rhs)) => NotOr(not, rhs),
(Not(not), HasOr(rhs, rhs_or)) => HasNotOr(rhs, not, rhs_or),
(Not(not), NotOr(rhs_not, rhs_or)) => NotOr(not | rhs_not, rhs_or),
(Not(not), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(rhs, not | rhs_not, rhs_or),
(Not(not), Option(option)) => NotOption(not, option),
(Not(not), HasOption(rhs_has, rhs_option)) => HasNotOption(rhs_has, not, rhs_option),
(Not(not), NotOption(rhs_not, rhs_option)) => NotOption(not | rhs_not, rhs_option),
(Not(not), OrOption(rhs_or, rhs_option)) => NotOrOption(not, rhs_or, rhs_option),
(Not(not), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(rhs_has, not | rhs_not, rhs_option),
(Not(not), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not, rhs_or, rhs_option),
(Not(not), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(not | rhs_not, rhs_or, rhs_option),
(Not(not), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not | rhs_not, rhs_or, rhs_option),
(Not(not), All) => Not(not),
(HasNot(has, not), HasNot(rhs, rhs_not)) => HasNot(has | rhs, not | rhs_not),
(HasNot(has, not), Or(rhs)) => HasNotOr(has, not, rhs),
(HasNot(has, not), HasOr(rhs, rhs_or)) => HasNotOr(has | rhs, not, rhs_or),
(HasNot(has, not), NotOr(rhs_not, rhs_or)) => HasNotOr(has, not | rhs_not, rhs_or),
(HasNot(has, not), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(has | rhs, not | rhs_not, rhs_or),
(HasNot(has, not), Option(option)) => HasNotOption(has, not, option),
(HasNot(has, not), HasOption(rhs_has, rhs_option)) => HasNotOption(has | rhs_has, not, rhs_option),
(HasNot(has, not), NotOption(rhs_not, rhs_option)) => HasNotOption(has, not | rhs_not, rhs_option),
(HasNot(has, not), OrOption(rhs_or, rhs_option)) => HasNotOrOption(has, not, rhs_or, rhs_option),
(HasNot(has, not), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(has | rhs_has, not | rhs_not, rhs_option),
(HasNot(has, not), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not, rhs_or, rhs_option),
(HasNot(has, not), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, not | rhs_not, rhs_or, rhs_option),
(HasNot(has, not), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not | rhs_not, rhs_or, rhs_option),
(HasNot(has, not), All) => HasNot(has, not),
(Or(or), Or(rhs)) => Or(or | rhs),
(Or(or), HasOr(rhs, rhs_or)) => HasOr(rhs, or | rhs_or),
(Or(or), NotOr(rhs_not, rhs_or)) => NotOr(rhs_not, or | rhs_or),
(Or(or), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(rhs, rhs_not, or | rhs_or),
(Or(or), Option(option)) => OrOption(or, option),
(Or(or), HasOption(rhs_has, rhs_option)) => HasOrOption(rhs_has, or, rhs_option),
(Or(or), NotOption(rhs_not, rhs_option)) => NotOrOption(rhs_not, or, rhs_option),
(Or(or), OrOption(rhs_or, rhs_option)) => OrOption(or | rhs_or, rhs_option),
(Or(or), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(rhs_has, rhs_not, or, rhs_option),
(Or(or), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(rhs_has, or | rhs_or, rhs_option),
(Or(or), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(rhs_not, or | rhs_or, rhs_option),
(Or(or), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, rhs_not, or | rhs_or, rhs_option),
(Or(or), All) => Or(or),
(HasOr(has, or), HasOr(rhs, rhs_or)) => HasOr(has | rhs, or | rhs_or),
(HasOr(has, or), NotOr(rhs_not, rhs_or)) => HasNotOr(has, rhs_not, or | rhs_or),
(HasOr(has, or), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(has | rhs, rhs_not, or | rhs_or),
(HasOr(has, or), Option(option)) => HasOrOption(has, or, option),
(HasOr(has, or), HasOption(rhs_has, rhs_option)) => HasOrOption(has | rhs_has, or, rhs_option),
(HasOr(has, or), NotOption(rhs_not, rhs_option)) => HasNotOrOption(has, rhs_not, or, rhs_option),
(HasOr(has, or), OrOption(rhs_or, rhs_option)) => HasOrOption(has, or | rhs_or, rhs_option),
(HasOr(has, or), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, or, rhs_option),
(HasOr(has, or), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(has | rhs_has, or | rhs_or, rhs_option),
(HasOr(has, or), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, rhs_not, or | rhs_or, rhs_option),
(HasOr(has, or), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, or | rhs_or, rhs_option),
(HasOr(has, or), All) => HasOr(has, or),
(NotOr(not, or), NotOr(rhs_not, rhs_or)) => NotOr(not | rhs_not, or | rhs_or),
(NotOr(not, or), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(rhs, not | rhs_not, or | rhs_or),
(NotOr(not, or), Option(option)) => NotOrOption(not, or, option),
(NotOr(not, or), HasOption(rhs_has, rhs_option)) => HasNotOrOption(rhs_has, not, or, rhs_option),
(NotOr(not, or), NotOption(rhs_not, rhs_option)) => NotOrOption(not | rhs_not, or, rhs_option),
(NotOr(not, or), OrOption(rhs_or, rhs_option)) => NotOrOption(not, or | rhs_or, rhs_option),
(NotOr(not, or), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(rhs_has, not | rhs_not, or, rhs_option),
(NotOr(not, or), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not, or | rhs_or, rhs_option),
(NotOr(not, or), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(not | rhs_not, or | rhs_or, rhs_option),
(NotOr(not, or), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not | rhs_not, or | rhs_or, rhs_option),
(NotOr(not, or), All) => NotOr(not, or),
(HasNotOr(has, not, or), HasNotOr(rhs, rhs_not, rhs_or)) => HasNotOr(has | rhs, not | rhs_not, or | rhs_or),
(HasNotOr(has, not, or), Option(option)) => HasNotOrOption(has, not, or, option),
(HasNotOr(has,not, or), HasOption(rhs_has, rhs_option)) => HasNotOrOption(has | rhs_has, not, or, rhs_option),
(HasNotOr(has,not, or), NotOption(rhs_not, rhs_option)) => HasNotOrOption(has, not | rhs_not, or, rhs_option),
(HasNotOr(has,not, or), OrOption(rhs_or, rhs_option)) => HasNotOrOption(has, not, or | rhs_or, rhs_option),
(HasNotOr(has,not, or), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(has | rhs_has, not | rhs_not, or, rhs_option),
(HasNotOr(has,not, or), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not, or | rhs_or, rhs_option),
(HasNotOr(has,not, or), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, not | rhs_not, or | rhs_or, rhs_option),
(HasNotOr(has,not, or), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not | rhs_not, or | rhs_or, rhs_option),
(HasNotOr(has, not, or), All) => HasNotOr(has, not, or),
(Option(option), Option(rhs_option)) => Option(option | rhs_option),
(Option(option), HasOption(rhs_has, rhs_option)) => HasOption(rhs_has, option | rhs_option),
(Option(option), NotOption(rhs_not, rhs_option)) => NotOption(rhs_not, option | rhs_option),
(Option(option), OrOption(rhs_or, rhs_option)) => OrOption(rhs_or, option | rhs_option),
(Option(option), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(rhs_has, rhs_not, option | rhs_option),
(Option(option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(rhs_has, rhs_or, option | rhs_option),
(Option(option), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(rhs_not, rhs_or, option | rhs_option),
(Option(option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, rhs_not, rhs_or, option | rhs_option),
(Option(option), All) => Option(option),
(HasOption(has, option), HasOption(rhs_has, rhs_option)) => HasOption(has | rhs_has, option | rhs_option),
(HasOption(has, option), NotOption(rhs_not, rhs_option)) => HasNotOption(has, rhs_not, option | rhs_option),
(HasOption(has, option), OrOption(rhs_or, rhs_option)) => HasOrOption(has, rhs_or, option | rhs_option),
(HasOption(has, option), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(has | rhs_has, rhs_not, option | rhs_option),
(HasOption(has, option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(has | rhs_has, rhs_or, option | rhs_option),
(HasOption(has, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, rhs_not, rhs_or, option | rhs_option),
(HasOption(has, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, rhs_or, option | rhs_option),
(HasOption(has, option), All) => HasOption(has, option),
(NotOption(not, option), NotOption(rhs_not, rhs_option)) => NotOption(not | rhs_not, option | rhs_option),
(NotOption(not, option), OrOption(rhs_or, rhs_option)) => NotOrOption(not, rhs_or, option | rhs_option),
(NotOption(not, option), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOption(rhs_has, not | rhs_not, option | rhs_option),
(NotOption(not, option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not, rhs_or, option | rhs_option),
(NotOption(not, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(not | rhs_not, rhs_or, option | rhs_option),
(NotOption(not, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not | rhs_not, rhs_or, option | rhs_option),
(NotOption(not, option), All) => NotOption(not, option),
(OrOption(or, option), OrOption(rhs_or, rhs_option)) => OrOption(or | rhs_or, option | rhs_option),
(OrOption(or, option), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(rhs_has, rhs_not, or, option | rhs_option),
(OrOption(or, option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(rhs_has, or | rhs_or, option | rhs_option),
(OrOption(or, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(rhs_not, or | rhs_or, option | rhs_option),
(OrOption(or, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, rhs_not, or | rhs_or, option | rhs_option),
(OrOption(or, option), All) => OrOption(or, option),
(HasNotOption(has, or, option), HasNotOption(rhs_has, rhs_not, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, or, option | rhs_option),
(HasNotOption(has, not, option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not, rhs_or, option | rhs_option),
(HasNotOption(has, not, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, not | rhs_not, rhs_or, option | rhs_option),
(HasNotOption(has, not, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not | rhs_not, rhs_or, option | rhs_option),
(HasNotOption(has, not, option), All) => HasNotOption(has, not, option),
(HasOrOption(has, or, option), HasOrOption(rhs_has, rhs_or, rhs_option)) => HasOrOption(has | rhs_has, or | rhs_or, option | rhs_option),
(HasOrOption(has, or, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has, rhs_not, or | rhs_or, option | rhs_option),
(HasOrOption(has, or, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, rhs_not, or | rhs_or, option | rhs_option),
(HasOrOption(has, or, option), All) => HasOrOption(has, or, option),
(NotOrOption(not, or, option), NotOrOption(rhs_not, rhs_or, rhs_option)) => NotOrOption(not | rhs_not, or | rhs_or, option | rhs_option),
(NotOrOption(not, or, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(rhs_has, not | rhs_not, or | rhs_or, option | rhs_option),
(NotOrOption(not, or, option), All) => NotOrOption(not, or, option),
(HasNotOrOption(has, not, or, option), HasNotOrOption(rhs_has, rhs_not, rhs_or, rhs_option)) => HasNotOrOption(has | rhs_has, not | rhs_not, or | rhs_or, option | rhs_option),
(HasNotOrOption(has, not, or, option), All) => HasNotOrOption(has, not, or, option),
(All, All) => All,
(Refs(mut refs), Refs(rhs_refs)) => {
refs.extend_from_slice(&rhs_refs);
Refs(refs)
},
(other, Refs(refs)) => OtherAndRefs(Box::new(other), refs),
(other, OtherAndRefs(rhs_other, refs)) => OtherAndRefs(Box::new(other | *rhs_other), refs),
(lhs, rhs) => rhs.bitor(lhs)
}
}
}