use std::ops::Not;
use {
super::ALWAYS_FALSE_NAME,
super::ALWAYS_TRUE_NAME,
super::BiPredicateFn,
crate::BiPredicate,
crate::predicates::macros::impl_predicate_clone,
crate::predicates::macros::impl_predicate_common_methods,
crate::predicates::macros::impl_predicate_debug_display,
crate::predicates::macros::impl_shared_predicate_methods,
std::rc::Rc,
};
#[must_use = "callback wrappers do nothing unless stored or invoked"]
pub struct RcBiPredicate<T, U> {
pub(super) function: Rc<BiPredicateFn<T, U>>,
pub(super) metadata: crate::internal::CallbackMetadata,
}
impl<T, U> RcBiPredicate<T, U> {
impl_predicate_common_methods!(
RcBiPredicate<T, U>,
semantic (BiPredicate<T, U> + 'static),
|predicate| move |first: &T, second: &U| predicate.test(first, second),
|f| Rc::new(f)
);
impl_shared_predicate_methods!(RcBiPredicate<T, U>, 'static);
}
impl<T, U> Not for RcBiPredicate<T, U>
where
T: 'static,
U: 'static,
{
type Output = RcBiPredicate<T, U>;
fn not(self) -> Self::Output {
let metadata = self.metadata;
let function = self.function;
RcBiPredicate::new_with_metadata(
move |first: &T, second: &U| !function(first, second),
metadata,
)
}
}
impl<T, U> Not for &RcBiPredicate<T, U>
where
T: 'static,
U: 'static,
{
type Output = RcBiPredicate<T, U>;
fn not(self) -> Self::Output {
let function = self.function.clone();
RcBiPredicate::new_with_metadata(
move |first: &T, second: &U| !function(first, second),
self.metadata.clone(),
)
}
}
impl_predicate_clone!(RcBiPredicate<T, U>);
impl_predicate_debug_display!(RcBiPredicate<T, U>);
impl<T, U> BiPredicate<T, U> for RcBiPredicate<T, U> {
#[inline(always)]
fn test(&self, first: &T, second: &U) -> bool {
(self.function)(first, second)
}
}