use std::hash::Hash;
use solverforge_core::score::Score;
use crate::constraint::IncrementalTriConstraint;
use super::collection_extract::CollectionExtract;
use super::filter::{FnQuadFilter, QuadFilter, TriFilter};
use super::joiner::Joiner;
use super::quad_stream::QuadConstraintStream;
super::arity_stream_macros::impl_arity_stream!(
tri,
TriConstraintStream,
TriConstraintBuilder,
IncrementalTriConstraint
);
impl<S, A, K, E, KE, F, Sc> TriConstraintStream<S, A, K, E, KE, F, Sc>
where
S: Send + Sync + 'static,
A: Clone + Hash + PartialEq + Send + Sync + 'static,
K: Eq + Hash + Clone + Send + Sync,
E: CollectionExtract<S, Item = A>,
KE: Fn(&S, &A, usize) -> K + Send + Sync,
F: TriFilter<S, A, A, A>,
Sc: Score + 'static,
{
pub fn join<J>(
self,
joiner: J,
) -> QuadConstraintStream<S, A, K, E, KE, impl QuadFilter<S, A, A, A, A>, Sc>
where
J: Joiner<A, A> + 'static,
F: 'static,
{
let filter = self.filter;
let combined_filter = move |s: &S,
a: &A,
b: &A,
c: &A,
d: &A,
a_idx: usize,
b_idx: usize,
c_idx: usize,
_d_idx: usize| {
filter.test(s, a, b, c, a_idx, b_idx, c_idx) && joiner.matches(a, d)
};
QuadConstraintStream::new_self_join_with_filter(
self.extractor,
self.key_extractor,
FnQuadFilter::new(combined_filter),
)
}
}
#[cfg(doctest)]
mod doctests {
}