use crate::eval::Evaluator;
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::{BitAndAssign, BitOrAssign, Sub};
#[derive(Clone)]
pub struct BitwiseEval<K, S> {
pub variables: HashMap<K, S>,
pub universal: S,
}
impl<K, S> BitwiseEval<K, S> {
pub fn new(universal: S) -> Self {
Self {
variables: HashMap::new(),
universal,
}
}
pub fn insert(&mut self, key: K, value: S)
where
K: Hash + Eq,
{
self.variables.insert(key, value);
}
}
impl<K, S> Evaluator<K, S, ()> for BitwiseEval<K, S>
where
K: Hash + Eq,
S: Default + Clone,
for<'a> S: BitOrAssign<&'a S> + BitAndAssign<&'a S>,
for<'a> &'a S: Sub<Output = S>,
{
fn get_universal(&mut self) -> Result<S, ()> {
Ok(self.universal.clone())
}
fn get_empty(&mut self) -> Result<S, ()> {
Ok(S::default())
}
fn eval_set(&mut self, key: &K) -> Result<S, ()> {
Ok(self.variables.remove(key).unwrap_or_default())
}
fn eval_union<'a, I>(&mut self, values: I) -> Result<S, ()>
where
S: 'a,
I: IntoIterator<Item = &'a S>,
I::IntoIter: ExactSizeIterator,
{
let mut iter = values.into_iter();
let mut result = iter.next().unwrap().clone();
for item in iter {
result |= item;
}
Ok(result)
}
fn eval_intersection<'a, I>(&mut self, values: I) -> Result<S, ()>
where
S: 'a,
I: IntoIterator<Item = &'a S>,
I::IntoIter: ExactSizeIterator,
{
let mut iter = values.into_iter();
let mut result = iter.next().unwrap().clone();
for item in iter {
result &= item;
}
Ok(result)
}
fn eval_difference(&mut self, include: &S, exclude: &S) -> Result<S, ()> {
Ok(include - exclude)
}
}