use std::hash::Hash;
use solverforge_core::score::Score;
use crate::constraint::IncrementalBiConstraint;
use super::filter::{BiFilter, FnTriFilter, TriFilter};
use super::joiner::Joiner;
use super::tri_stream::TriConstraintStream;
super::arity_stream_macros::impl_arity_stream!(
bi,
BiConstraintStream,
BiConstraintBuilder,
IncrementalBiConstraint
);
impl<S, A, K, E, KE, F, Sc> BiConstraintStream<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: super::collection_extract::CollectionExtract<S, Item = A>,
KE: Fn(&S, &A, usize) -> K + Send + Sync,
F: BiFilter<S, A, A>,
Sc: Score + 'static,
{
pub fn join<J>(
self,
joiner: J,
) -> TriConstraintStream<S, A, K, E, KE, impl TriFilter<S, 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, a_idx: usize, b_idx: usize, _c_idx: usize| {
filter.test(s, a, b, a_idx, b_idx) && joiner.matches(a, c)
};
TriConstraintStream::new_self_join_with_filter(
self.extractor,
self.key_extractor,
FnTriFilter::new(combined_filter),
)
}
}
#[cfg(doctest)]
mod doctests {
}