use crate::dedup::Keep;
pub use crate::iterators::VecSetIter;
use crate::merge_state::{
CloneConverter, IdConverter, InPlaceMergeState, InPlaceSmallVecMergeStateRef, NoConverter,
};
use crate::{
dedup::sort_dedup,
merge_state::{BoolOpMergeState, MergeStateMut, SmallVecMergeState},
};
use binary_merge::MergeOperation;
#[cfg(feature = "rkyv_validated")]
use bytecheck::CheckBytes;
use core::{
cmp::Ordering,
fmt, hash,
hash::Hash,
iter::FromIterator,
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign},
};
#[cfg(feature = "rkyv")]
use rkyv::{validation::ArchiveContext, Archive};
use smallvec::{Array, SmallVec};
use std::collections::BTreeSet;
#[cfg(feature = "serde")]
use {
core::marker::PhantomData,
serde::{
de::{Deserialize, Deserializer, SeqAccess, Visitor},
ser::{Serialize, SerializeSeq, Serializer},
},
};
struct SetUnionOp;
struct SetIntersectionOp;
struct SetXorOp;
struct SetDiffOpt;
#[derive(Default)]
pub struct VecSet<A: Array>(SmallVec<A>);
pub type VecSet2<T> = VecSet<[T; 2]>;
pub trait AbstractVecSet<T: Ord> {
fn as_slice(&self) -> &[T];
fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
fn contains(&self, value: &T) -> bool {
self.as_slice().binary_search(value).is_ok()
}
fn is_disjoint(&self, that: &impl AbstractVecSet<T>) -> bool {
!BoolOpMergeState::merge(self.as_slice(), that.as_slice(), SetIntersectionOp)
}
fn is_subset(&self, that: &impl AbstractVecSet<T>) -> bool {
!BoolOpMergeState::merge(self.as_slice(), that.as_slice(), SetDiffOpt)
}
fn is_superset(&self, that: &impl AbstractVecSet<T>) -> bool {
!BoolOpMergeState::merge(that.as_slice(), self.as_slice(), SetDiffOpt)
}
fn union<A: Array<Item = T>>(&self, that: &impl AbstractVecSet<T>) -> VecSet<A>
where
T: Clone,
{
VecSet(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetUnionOp,
CloneConverter,
))
}
fn intersection<A: Array<Item = T>>(&self, that: &impl AbstractVecSet<T>) -> VecSet<A>
where
T: Clone,
{
VecSet(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetIntersectionOp,
CloneConverter,
))
}
fn symmetric_difference<A: Array<Item = T>>(&self, that: &impl AbstractVecSet<T>) -> VecSet<A>
where
T: Clone,
{
VecSet(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetXorOp,
CloneConverter,
))
}
fn difference<A: Array<Item = T>>(&self, that: &impl AbstractVecSet<T>) -> VecSet<A>
where
T: Clone,
{
VecSet(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetDiffOpt,
CloneConverter,
))
}
fn iter(&self) -> VecSetIter<core::slice::Iter<T>> {
VecSetIter::new(self.as_slice().iter())
}
}
impl<A: Array> AbstractVecSet<A::Item> for VecSet<A>
where
A::Item: Ord,
{
fn as_slice(&self) -> &[A::Item] {
self.0.as_ref()
}
}
#[cfg(feature = "rkyv")]
impl<T> AbstractVecSet<T> for ArchivedVecSet<T>
where
T: Ord,
{
fn as_slice(&self) -> &[T] {
self.0.as_ref()
}
}
impl<T: fmt::Debug, A: Array<Item = T>> fmt::Debug for VecSet<A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T: Clone, A: Array<Item = T>> Clone for VecSet<A> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: Hash, A: Array<Item = T>> Hash for VecSet<A> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
impl<T: PartialEq, A: Array<Item = T>> PartialEq for VecSet<A> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T: Eq, A: Array<Item = T>> Eq for VecSet<A> {}
impl<T: PartialOrd, A: Array<Item = T>> PartialOrd for VecSet<A> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<T: Ord, A: Array<Item = T>> Ord for VecSet<A> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.cmp(&other.0)
}
}
impl<A: Array> VecSet<A> {
pub(crate) fn new_unsafe(a: SmallVec<A>) -> Self {
Self(a)
}
pub fn single(value: A::Item) -> Self {
let mut res = SmallVec::new();
res.push(value);
Self(res)
}
pub fn empty() -> Self {
Self::new_unsafe(SmallVec::new())
}
pub fn iter(&self) -> VecSetIter<core::slice::Iter<A::Item>> {
VecSetIter::new(self.0.iter())
}
fn as_slice(&self) -> &[A::Item] {
&self.0
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn into_inner(self) -> SmallVec<A> {
self.0
}
}
impl<A: Array> VecSet<A>
where
A::Item: Ord,
{
pub fn insert(&mut self, that: A::Item) -> bool {
match self.0.binary_search(&that) {
Ok(index) => {
self.0[index] = that;
false
}
Err(index) => {
self.0.insert(index, that);
true
}
}
}
pub fn remove(&mut self, that: &A::Item) -> bool {
if let Ok(index) = self.0.binary_search(that) {
self.0.remove(index);
true
} else {
false
}
}
pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, mut f: F) {
self.0.retain(|entry| f(entry))
}
fn from_vec(vec: Vec<A::Item>) -> Self {
let mut vec = vec;
vec.sort();
vec.dedup();
Self::new_unsafe(SmallVec::from_vec(vec))
}
}
impl<'a, A: Array> IntoIterator for &'a VecSet<A> {
type Item = &'a A::Item;
type IntoIter = VecSetIter<core::slice::Iter<'a, A::Item>>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<A: Array> IntoIterator for VecSet<A> {
type Item = A::Item;
type IntoIter = VecSetIter<smallvec::IntoIter<A>>;
fn into_iter(self) -> Self::IntoIter {
VecSetIter::new(self.0.into_iter())
}
}
impl<A: Array> From<VecSet<A>> for Vec<A::Item> {
fn from(value: VecSet<A>) -> Self {
value.0.into_vec()
}
}
impl<A: Array> From<VecSet<A>> for SmallVec<A> {
fn from(value: VecSet<A>) -> Self {
value.into_inner()
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitAnd<&VecSet<B>> for &VecSet<A> {
type Output = VecSet<A>;
fn bitand(self, that: &VecSet<B>) -> Self::Output {
self.intersection(that)
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitOr<&VecSet<B>> for &VecSet<A> {
type Output = VecSet<A>;
fn bitor(self, that: &VecSet<B>) -> Self::Output {
self.union(that)
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitXor<&VecSet<B>> for &VecSet<A> {
type Output = VecSet<A>;
fn bitxor(self, that: &VecSet<B>) -> Self::Output {
self.symmetric_difference(that)
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> Sub<&VecSet<B>> for &VecSet<A> {
type Output = VecSet<A>;
fn sub(self, that: &VecSet<B>) -> Self::Output {
self.difference(that)
}
}
impl<T: Ord, A: Array<Item = T>, B: Array<Item = T>> BitAndAssign<VecSet<B>> for VecSet<A> {
fn bitand_assign(&mut self, that: VecSet<B>) {
InPlaceMergeState::merge(&mut self.0, that.0, SetIntersectionOp, IdConverter);
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitAndAssign<&VecSet<B>>
for VecSet<A>
{
fn bitand_assign(&mut self, that: &VecSet<B>) {
InPlaceSmallVecMergeStateRef::merge(
&mut self.0,
&that.0,
SetIntersectionOp,
CloneConverter,
);
}
}
impl<T: Ord, A: Array<Item = T>, B: Array<Item = T>> BitOrAssign<VecSet<B>> for VecSet<A> {
fn bitor_assign(&mut self, that: VecSet<B>) {
InPlaceMergeState::merge(&mut self.0, that.0, SetUnionOp, IdConverter);
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitOrAssign<&VecSet<B>> for VecSet<A> {
fn bitor_assign(&mut self, that: &VecSet<B>) {
InPlaceSmallVecMergeStateRef::merge(&mut self.0, &that.0, SetUnionOp, CloneConverter);
}
}
impl<T: Ord, A: Array<Item = T>, B: Array<Item = T>> BitXorAssign<VecSet<B>> for VecSet<A> {
fn bitxor_assign(&mut self, that: VecSet<B>) {
InPlaceMergeState::merge(&mut self.0, that.0, SetXorOp, IdConverter);
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> BitXorAssign<&VecSet<B>>
for VecSet<A>
{
fn bitxor_assign(&mut self, that: &VecSet<B>) {
InPlaceSmallVecMergeStateRef::merge(&mut self.0, &that.0, SetXorOp, CloneConverter);
}
}
impl<T: Ord, A: Array<Item = T>, B: Array<Item = T>> SubAssign<VecSet<B>> for VecSet<A> {
fn sub_assign(&mut self, that: VecSet<B>) {
InPlaceMergeState::merge(&mut self.0, that.0, SetDiffOpt, IdConverter);
}
}
impl<T: Ord + Clone, A: Array<Item = T>, B: Array<Item = T>> SubAssign<&VecSet<B>> for VecSet<A> {
fn sub_assign(&mut self, that: &VecSet<B>) {
InPlaceSmallVecMergeStateRef::merge(&mut self.0, &that.0, SetDiffOpt, CloneConverter);
}
}
impl<A: Array> AsRef<[A::Item]> for VecSet<A> {
fn as_ref(&self) -> &[A::Item] {
self.as_slice()
}
}
impl<T: Ord, A: Array<Item = T>> From<Vec<T>> for VecSet<A> {
fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec)
}
}
impl<T: Ord, A: Array<Item = T>> From<BTreeSet<T>> for VecSet<A> {
fn from(value: BTreeSet<T>) -> Self {
Self::new_unsafe(value.into_iter().collect())
}
}
impl<T: Ord, A: Array<Item = T>> FromIterator<T> for VecSet<A> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut vec: SmallVec<A> = sort_dedup(iter.into_iter(), Keep::First);
vec.shrink_to_fit();
Self::new_unsafe(vec)
}
}
impl<T: Ord, A: Array<Item = T>> Extend<T> for VecSet<A> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
*self |= Self::from_iter(iter);
}
}
impl<T: Ord, I: MergeStateMut<A = T, B = T>> MergeOperation<I> for SetUnionOp {
fn cmp(&self, a: &T, b: &T) -> Ordering {
a.cmp(b)
}
fn from_a(&self, m: &mut I, n: usize) -> bool {
m.advance_a(n, true)
}
fn from_b(&self, m: &mut I, n: usize) -> bool {
m.advance_b(n, true)
}
fn collision(&self, m: &mut I) -> bool {
m.advance_a(1, true) && m.advance_b(1, false)
}
}
impl<T: Ord, I: MergeStateMut<A = T, B = T>> MergeOperation<I> for SetIntersectionOp {
fn cmp(&self, a: &T, b: &T) -> Ordering {
a.cmp(b)
}
fn from_a(&self, m: &mut I, n: usize) -> bool {
m.advance_a(n, false)
}
fn from_b(&self, m: &mut I, n: usize) -> bool {
m.advance_b(n, false)
}
fn collision(&self, m: &mut I) -> bool {
m.advance_a(1, true) && m.advance_b(1, false)
}
}
impl<T: Ord, I: MergeStateMut<A = T, B = T>> MergeOperation<I> for SetDiffOpt {
fn cmp(&self, a: &T, b: &T) -> Ordering {
a.cmp(b)
}
fn from_a(&self, m: &mut I, n: usize) -> bool {
m.advance_a(n, true)
}
fn from_b(&self, m: &mut I, n: usize) -> bool {
m.advance_b(n, false)
}
fn collision(&self, m: &mut I) -> bool {
m.advance_a(1, false) && m.advance_b(1, false)
}
}
impl<T: Ord, I: MergeStateMut<A = T, B = T>> MergeOperation<I> for SetXorOp {
fn cmp(&self, a: &T, b: &T) -> Ordering {
a.cmp(b)
}
fn from_a(&self, m: &mut I, n: usize) -> bool {
m.advance_a(n, true)
}
fn from_b(&self, m: &mut I, n: usize) -> bool {
m.advance_b(n, true)
}
fn collision(&self, m: &mut I) -> bool {
m.advance_a(1, false) && m.advance_b(1, false)
}
}
#[cfg(feature = "serde")]
impl<A: Array> Serialize for VecSet<A>
where
A::Item: Serialize,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut state = serializer.serialize_seq(Some(self.len()))?;
for item in self.iter() {
state.serialize_element(&item)?;
}
state.end()
}
}
#[cfg(feature = "serde")]
impl<'de, A: Array> Deserialize<'de> for VecSet<A>
where
A::Item: Deserialize<'de> + Ord,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(VecSetVisitor {
phantom: PhantomData,
})
}
}
#[cfg(feature = "serde")]
struct VecSetVisitor<A> {
phantom: PhantomData<A>,
}
#[cfg(feature = "serde")]
impl<'de, A: Array> Visitor<'de> for VecSetVisitor<A>
where
A::Item: Deserialize<'de> + Ord,
{
type Value = VecSet<A>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
where
B: SeqAccess<'de>,
{
let len = seq.size_hint().unwrap_or(0);
let mut values = SmallVec::with_capacity(len);
while let Some(value) = seq.next_element()? {
values.push(value);
}
values.sort();
values.dedup();
Ok(VecSet(values))
}
}
#[cfg(feature = "rkyv")]
#[repr(transparent)]
pub struct ArchivedVecSet<T>(rkyv::vec::ArchivedVec<T>);
#[cfg(feature = "rkyv")]
impl<A> rkyv::Archive for VecSet<A>
where
A: Array,
A::Item: rkyv::Archive,
{
type Archived = ArchivedVecSet<<A::Item as rkyv::Archive>::Archived>;
type Resolver = rkyv::vec::VecResolver;
unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
rkyv::vec::ArchivedVec::resolve_from_slice(self.0.as_slice(), pos, resolver, &mut (*out).0);
}
}
#[cfg(feature = "rkyv")]
impl<S, T, A> rkyv::Serialize<S> for VecSet<A>
where
A: Array<Item = T>,
T: rkyv::Archive + rkyv::Serialize<S>,
S: rkyv::ser::ScratchSpace + rkyv::ser::Serializer,
{
fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
rkyv::vec::ArchivedVec::serialize_from_slice(self.0.as_ref(), serializer)
}
}
#[cfg(feature = "rkyv")]
impl<D, T, A> rkyv::Deserialize<VecSet<A>, D> for ArchivedVecSet<T::Archived>
where
A: Array<Item = T>,
T: rkyv::Archive,
D: rkyv::Fallible + ?Sized,
[<<A as Array>::Item as rkyv::Archive>::Archived]:
rkyv::DeserializeUnsized<[<A as Array>::Item], D>,
{
fn deserialize(&self, deserializer: &mut D) -> Result<VecSet<A>, D::Error> {
let items: Vec<A::Item> = self.0.deserialize(deserializer)?;
Ok(VecSet(items.into()))
}
}
#[cfg(feature = "rkyv_validated")]
#[derive(Debug)]
pub enum ArchivedVecSetError {
ValueCheckError,
OrderCheckError,
}
#[cfg(feature = "rkyv_validated")]
impl std::error::Error for ArchivedVecSetError {}
#[cfg(feature = "rkyv_validated")]
impl std::fmt::Display for ArchivedVecSetError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[cfg(feature = "rkyv_validated")]
impl<C: ?Sized, T> bytecheck::CheckBytes<C> for ArchivedVecSet<T>
where
C: ArchiveContext,
C::Error: std::error::Error,
T: Ord + Archive + CheckBytes<C>,
bool: bytecheck::CheckBytes<C>,
{
type Error = ArchivedVecSetError;
unsafe fn check_bytes<'a>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, Self::Error> {
let values = &(*value).0;
CheckBytes::check_bytes(values, context)
.map_err(|_| ArchivedVecSetError::ValueCheckError)?;
if !values.iter().zip(values.iter().skip(1)).all(|(a, b)| a < b) {
return Err(ArchivedVecSetError::OrderCheckError);
};
Ok(&*value)
}
}
impl<A: Array> VecSet<A>
where
A::Item: Ord + Clone,
{
pub fn union(&self, that: &impl AbstractVecSet<A::Item>) -> Self {
Self(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetUnionOp,
CloneConverter,
))
}
pub fn intersection(&self, that: &impl AbstractVecSet<A::Item>) -> Self {
Self(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetIntersectionOp,
CloneConverter,
))
}
pub fn symmetric_difference(&self, that: &impl AbstractVecSet<A::Item>) -> Self {
Self(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetXorOp,
CloneConverter,
))
}
pub fn difference(&self, that: &impl AbstractVecSet<A::Item>) -> Self {
Self(SmallVecMergeState::merge(
self.as_slice(),
that.as_slice(),
SetDiffOpt,
CloneConverter,
))
}
pub fn union_with(&mut self, that: &impl AbstractVecSet<A::Item>) {
InPlaceSmallVecMergeStateRef::merge(&mut self.0, &that.as_slice(), SetUnionOp, NoConverter);
}
pub fn intersection_with(&mut self, that: &impl AbstractVecSet<A::Item>) {
InPlaceSmallVecMergeStateRef::merge(
&mut self.0,
&that.as_slice(),
SetIntersectionOp,
NoConverter,
);
}
pub fn xor_with(&mut self, that: &impl AbstractVecSet<A::Item>) {
InPlaceSmallVecMergeStateRef::merge(
&mut self.0,
&that.as_slice(),
SetIntersectionOp,
NoConverter,
);
}
pub fn difference_with(&mut self, that: &impl AbstractVecSet<A::Item>) {
InPlaceSmallVecMergeStateRef::merge(&mut self.0, &that.as_slice(), SetDiffOpt, NoConverter);
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::vec_set::AbstractVecSet;
use num_traits::PrimInt;
use obey::*;
use quickcheck::*;
#[test]
fn drop_pointer_being_freed_was_not_allocated() {
let mut tags: VecSet<[Box<str>; 4]> = VecSet::default();
tags.bitor_assign(VecSet::<[Box<str>; 4]>::single("a".into()));
let sv = tags.into_inner();
std::mem::drop(sv);
}
impl<T: Arbitrary + Ord + Copy + Default + fmt::Debug> Arbitrary for VecSet<[T; 2]> {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
Self::from_vec(Arbitrary::arbitrary(g))
}
}
impl<E: PrimInt> TestSamples<E, bool> for VecSet<[E; 2]> {
fn samples(&self, res: &mut BTreeSet<E>) {
res.insert(E::min_value());
for x in self.0.iter().cloned() {
res.insert(x - E::one());
res.insert(x);
res.insert(x + E::one());
}
res.insert(E::max_value());
}
fn at(&self, elem: E) -> bool {
self.contains(&elem)
}
}
type Test = VecSet<[i64; 2]>;
type Reference = BTreeSet<i64>;
quickcheck! {
#[cfg(feature = "serde")]
fn serde_roundtrip(reference: Test) -> bool {
let bytes = serde_json::to_vec(&reference).unwrap();
let deser = serde_json::from_slice(&bytes).unwrap();
reference == deser
}
#[cfg(feature = "rkyv")]
fn rkyv_roundtrip_unvalidated(a: Test) -> bool {
use rkyv::*;
use ser::Serializer;
let mut serializer = ser::serializers::AllocSerializer::<256>::default();
serializer.serialize_value(&a).unwrap();
let bytes = serializer.into_serializer().into_inner();
let archived = unsafe { rkyv::archived_root::<Test>(&bytes) };
let deserialized: Test = archived.deserialize(&mut Infallible).unwrap();
a == deserialized
}
#[cfg(feature = "rkyv_validated")]
#[quickcheck]
fn rkyv_roundtrip_validated(a: Test) -> bool {
use rkyv::*;
use ser::Serializer;
let mut serializer = ser::serializers::AllocSerializer::<256>::default();
serializer.serialize_value(&a).unwrap();
let bytes = serializer.into_serializer().into_inner();
let archived = rkyv::check_archived_root::<Test>(&bytes).unwrap();
let deserialized: Test = archived.deserialize(&mut Infallible).unwrap();
a == deserialized
}
fn is_disjoint_sample(a: Test, b: Test) -> bool {
binary_property_test(&a, &b, a.is_disjoint(&b), |a, b| !(a & b))
}
fn is_subset_sample(a: Test, b: Test) -> bool {
binary_property_test(&a, &b, a.is_subset(&b), |a, b| !a | b)
}
fn union_sample(a: Test, b: Test) -> bool {
binary_element_test(&a, &b, &a | &b, |a, b| a | b)
}
fn intersection_sample(a: Test, b: Test) -> bool {
binary_element_test(&a, &b, &a & &b, |a, b| a & b)
}
fn xor_sample(a: Test, b: Test) -> bool {
binary_element_test(&a, &b, &a ^ &b, |a, b| a ^ b)
}
fn diff_sample(a: Test, b: Test) -> bool {
binary_element_test(&a, &b, &a - &b, |a, b| a & !b)
}
fn union(a: Reference, b: Reference) -> bool {
let mut a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let r2 = &a1 | &b1;
a1 |= b1;
println!("{:?} {:?}", a, b);
let expected: Vec<i64> = a.union(&b).cloned().collect();
let actual: Vec<i64> = a1.into();
let actual2: Vec<i64> = r2.into();
expected == actual && expected == actual2
}
fn intersection(a: Reference, b: Reference) -> bool {
let mut a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let r2 = &a1 & &b1;
a1 &= b1;
let expected: Vec<i64> = a.intersection(&b).cloned().collect();
let actual: Vec<i64> = a1.into();
let actual2: Vec<i64> = r2.into();
expected == actual && expected == actual2
}
fn xor(a: Reference, b: Reference) -> bool {
let mut a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let r2 = &a1 ^ &b1;
a1 ^= b1;
let expected: Vec<i64> = a.symmetric_difference(&b).cloned().collect();
let actual: Vec<i64> = a1.into();
let actual2: Vec<i64> = r2.into();
expected == actual && expected == actual2
}
fn difference(a: Reference, b: Reference) -> bool {
let mut a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let r2 = &a1 - &b1;
a1 -= b1;
let expected: Vec<i64> = a.difference(&b).cloned().collect();
let actual: Vec<i64> = a1.into();
let actual2: Vec<i64> = r2.into();
expected == actual && expected == actual2
}
fn is_disjoint(a: Reference, b: Reference) -> bool {
let a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let actual = a1.is_disjoint(&b1);
let expected = a.is_disjoint(&b);
expected == actual
}
fn is_subset(a: Reference, b: Reference) -> bool {
let a1: Test = a.iter().cloned().collect();
let b1: Test = b.iter().cloned().collect();
let actual = a1.is_subset(&b1);
let expected = a.is_subset(&b);
expected == actual
}
fn contains(a: Reference, b: i64) -> bool {
let a1: Test = a.iter().cloned().collect();
let expected = a.contains(&b);
let actual = a1.contains(&b);
expected == actual
}
}
bitop_assign_consistent!(Test);
set_predicate_consistent!(Test);
bitop_symmetry!(Test);
bitop_empty!(Test);
}