use core::ops::{BitAnd, BitOr, BitXor, Index, Sub};
use super::VecSet;
use alloc::vec::Vec;
impl<T> Default for VecSet<T> {
fn default() -> Self {
VecSet::new()
}
}
impl<T> Index<usize> for VecSet<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
self.get_index(index).expect("VecSet: index out of bounds")
}
}
impl<T> Extend<T> for VecSet<T>
where
T: Eq,
{
fn extend<I>(&mut self, iterable: I)
where
I: IntoIterator<Item = T>,
{
iterable.into_iter().for_each(|value| {
self.insert(value);
});
}
}
impl<'a, T> Extend<&'a T> for VecSet<T>
where
T: 'a + Copy + Eq,
{
fn extend<I>(&mut self, iterable: I)
where
I: IntoIterator<Item = &'a T>,
{
self.base.extend(iterable.into_iter().copied());
}
}
impl<T> FromIterator<T> for VecSet<T>
where
T: Eq,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
let mut set = VecSet::new();
set.extend(iter);
set
}
}
impl<T> From<Vec<T>> for VecSet<T>
where
T: Eq,
{
fn from(mut vec: Vec<T>) -> Self {
crate::dedup_keep_first(&mut vec, |lhs, rhs| lhs == rhs);
unsafe { Self::from_vec_unchecked(vec) }
}
}
impl<T> From<&[T]> for VecSet<T>
where
T: Clone + Eq,
{
fn from(slice: &[T]) -> Self {
slice.iter().cloned().collect()
}
}
impl<T> From<&mut [T]> for VecSet<T>
where
T: Clone + Eq,
{
fn from(slice: &mut [T]) -> Self {
slice.iter().cloned().collect()
}
}
impl<T, const N: usize> From<[T; N]> for VecSet<T>
where
T: Eq,
{
fn from(arr: [T; N]) -> Self {
VecSet::from_iter(arr)
}
}
impl<T> PartialEq for VecSet<T>
where
T: Eq,
{
fn eq(&self, other: &VecSet<T>) -> bool {
self.base == other.base
}
}
impl<T> Eq for VecSet<T> where T: Eq {}
impl<T> BitAnd<&VecSet<T>> for &VecSet<T>
where
T: Eq + Clone,
{
type Output = VecSet<T>;
fn bitand(self, other: &VecSet<T>) -> Self::Output {
self.intersection(other).cloned().collect()
}
}
impl<T> BitOr<&VecSet<T>> for &VecSet<T>
where
T: Eq + Clone,
{
type Output = VecSet<T>;
fn bitor(self, other: &VecSet<T>) -> Self::Output {
self.union(other).cloned().collect()
}
}
impl<T> BitXor<&VecSet<T>> for &VecSet<T>
where
T: Eq + Clone,
{
type Output = VecSet<T>;
fn bitxor(self, other: &VecSet<T>) -> Self::Output {
self.symmetric_difference(other).cloned().collect()
}
}
impl<T> Sub<&VecSet<T>> for &VecSet<T>
where
T: Eq + Clone,
{
type Output = VecSet<T>;
fn sub(self, other: &VecSet<T>) -> Self::Output {
self.difference(other).cloned().collect()
}
}
#[cfg(test)]
mod test {
use super::*;
extern crate alloc;
use alloc::vec;
#[derive(Clone, Debug)]
#[allow(dead_code)]
struct Item(i32, &'static str);
impl Eq for Item {}
impl PartialEq for Item {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
fn set_via_inserts(items: &[Item]) -> VecSet<Item> {
let mut set = VecSet::new();
for item in items {
set.insert(item.clone());
}
set
}
#[test]
fn constructor_parity_with_insert() {
let input = vec![Item(1, "first"), Item(2, "b"), Item(1, "second")];
let expected = set_via_inserts(&[Item(1, "first"), Item(2, "b"), Item(1, "second")]);
assert_eq!(VecSet::from(input.clone()), expected);
assert_eq!(input.into_iter().collect::<VecSet<_>>(), expected);
assert_eq!(
VecSet::from([Item(1, "first"), Item(2, "b"), Item(1, "second")]),
expected
);
assert_eq!(expected.as_slice(), &[Item(1, "first"), Item(2, "b")]);
}
#[test]
fn insert_rejects_duplicate_without_replacing() {
let mut set = VecSet::new();
assert!(set.insert(Item(1, "first")));
assert!(!set.insert(Item(1, "second")));
assert_eq!(set.as_slice(), &[Item(1, "first")]);
}
#[test]
fn extend_parity_with_insert() {
let mut via_extend = VecSet::new();
via_extend.extend([Item(1, "first"), Item(2, "b"), Item(1, "second")]);
let via_insert = set_via_inserts(&[Item(1, "first"), Item(2, "b"), Item(1, "second")]);
assert_eq!(via_extend, via_insert);
}
#[test]
fn append_parity_with_insert() {
let mut base = set_via_inserts(&[Item(1, "first")]);
let mut extra = VecSet::from(vec![Item(1, "second"), Item(2, "b")]);
base.append(&mut extra);
let expected = set_via_inserts(&[Item(1, "first"), Item(1, "second"), Item(2, "b")]);
assert_eq!(base, expected);
assert!(extra.is_empty());
}
}