use internal::*;
meta!{
pub type SetIntersection<
K: EqualityComparableKind,
S1: Expr<Set<K>>,
S2: Expr<Set<K>>
>: Expr<Set<K>> =
VisitSet<K, Set<K>, S1, SetIntersectionVisitor<K, S2, EmptySet<K>>>;
}
mod internal {
pub use super::super::internal::*;
use crate::bool::*;
meta!{
pub struct SetIntersectionVisitor<
K: EqualityComparableKind,
S: Expr<Set<K>>,
ResultS: Expr<Set<K>>
>: SetVisitor<K, Set<K>> {
type VisitEmptySet = ResultS;
type VisitCons<Elem: Expr<K>, Tail: Expr<Set<K>>> =
VisitSet<K, Set<K>, Tail, SetIntersectionVisitor<K, S,
If<Set<K>,
IsInSet<K, Elem, S>,
AddToSet<K, Elem, ResultS>,
ResultS
>>>;
}
}
}
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use crate::*;
use super::super::*;
use crate::r#type::*;
#[test]
fn is_empty_set_and_empty_set() {
meta_assert_eq!(Set<Type>, SetIntersection<Type, EmptySet<Type>, EmptySet<Type>>, EmptySet<Type>);
}
#[test]
fn is_non_empty_set_and_empty_set() {
type S = AddToSet<Type, WrapType<i32>, EmptySet<Type>>;
meta_assert_eq!(Set<Type>, SetIntersection<Type, S, EmptySet<Type>>, EmptySet<Type>);
}
#[test]
fn is_empty_set_and_non_empty_set() {
type S = AddToSet<Type, WrapType<i32>, EmptySet<Type>>;
meta_assert_eq!(Set<Type>, SetIntersection<Type, EmptySet<Type>, S>, EmptySet<Type>);
}
#[test]
fn intersection_subset() {
type S1 = AddToSet<Type, WrapType<i32>, AddToSet<Type, WrapType<f64>, EmptySet<Type>>>;
type S2 = AddToSet<Type, WrapType<u32>, AddToSet<Type, WrapType<i32>, AddToSet<Type, WrapType<u64>, AddToSet<Type, WrapType<f64>, EmptySet<Type>>>>>;
meta_assert_eq!(Set<Type>, SetIntersection<Type, S1, S2>, S1);
}
#[test]
fn intersection_superset() {
type S1 = AddToSet<Type, WrapType<u32>, AddToSet<Type, WrapType<i32>, AddToSet<Type, WrapType<u64>, AddToSet<Type, WrapType<f64>, EmptySet<Type>>>>>;
type S2 = AddToSet<Type, WrapType<i32>, AddToSet<Type, WrapType<f64>, EmptySet<Type>>>;
meta_assert_eq!(Set<Type>, SetIntersection<Type, S1, S2>, S2);
}
#[test]
fn intersection_general() {
type S1 = AddToSet<Type, WrapType<u32>, AddToSet<Type, WrapType<i32>, EmptySet<Type>>>;
type S2 = AddToSet<Type, WrapType<i32>, AddToSet<Type, WrapType<f64>, EmptySet<Type>>>;
type S3 = AddToSet<Type, WrapType<i32>, EmptySet<Type>>;
meta_assert_eq!(Set<Type>, SetIntersection<Type, S1, S2>, S3);
}
}