macro_rules! impl_shared_predicate_methods {
(
@logical_ops
$struct_name:ident < $t:ident >,
$predicate_trait_name:ident,
$($predicate_extra_bounds:tt)+
) => {
#[inline]
pub fn and<P>(&self, other: P) -> $struct_name<$t>
where
$t: 'static,
P: $predicate_trait_name<$t> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x| self_fn(x) && other.test(x))
}
#[inline]
pub fn or<P>(&self, other: P) -> $struct_name<$t>
where
$t: 'static,
P: $predicate_trait_name<$t> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x| self_fn(x) || other.test(x))
}
#[allow(clippy::should_implement_trait)]
#[inline]
pub fn not(&self) -> $struct_name<$t>
where
$t: 'static,
{
let self_fn = self.function.clone();
$struct_name::new(move |x| !(self_fn(x)))
}
#[inline]
pub fn nand<P>(&self, other: P) -> $struct_name<$t>
where
$t: 'static,
P: $predicate_trait_name<$t> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x| !(self_fn(x) && other.test(x)))
}
#[inline]
pub fn xor<P>(&self, other: P) -> $struct_name<$t>
where
$t: 'static,
P: $predicate_trait_name<$t> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x| self_fn(x) ^ other.test(x))
}
#[inline]
pub fn nor<P>(&self, other: P) -> $struct_name<$t>
where
$t: 'static,
P: $predicate_trait_name<$t> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x| !(self_fn(x) || other.test(x)))
}
};
(
@logical_ops
$struct_name:ident < $t:ident, $u:ident >,
$predicate_trait_name:ident,
$($predicate_extra_bounds:tt)+
) => {
#[inline]
pub fn and<P>(&self, other: P) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
P: $predicate_trait_name<$t, $u> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| self_fn(x, y) && other.test(x, y))
}
#[inline]
pub fn or<P>(&self, other: P) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
P: $predicate_trait_name<$t, $u> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| self_fn(x, y) || other.test(x, y))
}
#[allow(clippy::should_implement_trait)]
#[inline]
pub fn not(&self) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| !(self_fn(x, y)))
}
#[inline]
pub fn nand<P>(&self, other: P) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
P: $predicate_trait_name<$t, $u> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| !(self_fn(x, y) && other.test(x, y)))
}
#[inline]
pub fn xor<P>(&self, other: P) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
P: $predicate_trait_name<$t, $u> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| self_fn(x, y) ^ other.test(x, y))
}
#[inline]
pub fn nor<P>(&self, other: P) -> $struct_name<$t, $u>
where
$t: 'static,
$u: 'static,
P: $predicate_trait_name<$t, $u> + $($predicate_extra_bounds)+
{
let self_fn = self.function.clone();
$struct_name::new(move |x, y| !(self_fn(x, y) || other.test(x, y)))
}
};
(
$struct_name:ident < $t:ident >,
$($predicate_extra_bounds:tt)+
) => {
impl_shared_predicate_methods!(
@logical_ops $struct_name<$t>,
Predicate,
$($predicate_extra_bounds)+,
);
};
(
$struct_name:ident < $t:ident, $u:ident >,
$($predicate_extra_bounds:tt)+
) => {
impl_shared_predicate_methods!(
@logical_ops $struct_name<$t, $u>,
BiPredicate,
$($predicate_extra_bounds)+,
);
};
}
pub(crate) use impl_shared_predicate_methods;