use std::ops::Not;
use super::ALWAYS_FALSE_NAME;
use super::ALWAYS_TRUE_NAME;
use crate::StatefulPredicate;
use crate::predicates::macros::impl_predicate_common_methods;
use crate::predicates::macros::impl_predicate_debug_display;
#[must_use = "callback wrappers do nothing unless stored or invoked"]
pub struct BoxStatefulPredicate<T> {
pub(super) function: Box<dyn FnMut(&T) -> bool>,
pub(super) metadata: crate::internal::CallbackMetadata,
}
impl<T> BoxStatefulPredicate<T> {
impl_predicate_common_methods!(BoxStatefulPredicate<T>, (FnMut(&T) -> bool + 'static), |f| Box::new(f));
#[inline]
pub fn and<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
where
P: StatefulPredicate<T> + 'static,
T: 'static,
{
BoxStatefulPredicate::new(move |value: &T| self.test(value) && other.test(value))
}
#[inline]
pub fn or<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
where
P: StatefulPredicate<T> + 'static,
T: 'static,
{
BoxStatefulPredicate::new(move |value: &T| self.test(value) || other.test(value))
}
#[inline]
pub fn nand<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
where
P: StatefulPredicate<T> + 'static,
T: 'static,
{
BoxStatefulPredicate::new(move |value: &T| !(self.test(value) && other.test(value)))
}
#[inline]
pub fn xor<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
where
P: StatefulPredicate<T> + 'static,
T: 'static,
{
BoxStatefulPredicate::new(move |value: &T| self.test(value) ^ other.test(value))
}
#[inline]
pub fn nor<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
where
P: StatefulPredicate<T> + 'static,
T: 'static,
{
BoxStatefulPredicate::new(move |value: &T| !(self.test(value) || other.test(value)))
}
}
impl<T> Not for BoxStatefulPredicate<T>
where
T: 'static,
{
type Output = BoxStatefulPredicate<T>;
fn not(self) -> Self::Output {
let metadata = self.metadata;
let mut function = self.function;
BoxStatefulPredicate::new_with_metadata(move |value: &T| !function(value), metadata)
}
}
impl_predicate_debug_display!(BoxStatefulPredicate<T>);
impl<T> StatefulPredicate<T> for BoxStatefulPredicate<T> {
#[inline(always)]
fn test(&mut self, value: &T) -> bool {
(self.function)(value)
}
}