Skip to main content

vecmap/set/
impls.rs

1use core::ops::{BitAnd, BitOr, BitXor, Index, Sub};
2
3use super::VecSet;
4use alloc::vec::Vec;
5
6impl<T> Default for VecSet<T> {
7    fn default() -> Self {
8        VecSet::new()
9    }
10}
11
12impl<T> Index<usize> for VecSet<T> {
13    type Output = T;
14
15    fn index(&self, index: usize) -> &T {
16        self.get_index(index).expect("VecSet: index out of bounds")
17    }
18}
19
20impl<T> Extend<T> for VecSet<T>
21where
22    T: Eq,
23{
24    fn extend<I>(&mut self, iterable: I)
25    where
26        I: IntoIterator<Item = T>,
27    {
28        iterable.into_iter().for_each(|value| {
29            self.insert(value);
30        });
31    }
32}
33
34impl<'a, T> Extend<&'a T> for VecSet<T>
35where
36    T: 'a + Copy + Eq,
37{
38    fn extend<I>(&mut self, iterable: I)
39    where
40        I: IntoIterator<Item = &'a T>,
41    {
42        self.base.extend(iterable.into_iter().copied());
43    }
44}
45
46impl<T> FromIterator<T> for VecSet<T>
47where
48    T: Eq,
49{
50    fn from_iter<I>(iter: I) -> Self
51    where
52        I: IntoIterator<Item = T>,
53    {
54        let mut set = VecSet::new();
55        set.extend(iter);
56        set
57    }
58}
59
60impl<T> From<Vec<T>> for VecSet<T>
61where
62    T: Eq,
63{
64    /// Constructs set from a vector.
65    ///
66    /// When the input contains equal elements, the first occurrence is kept and
67    /// later equal values are ignored — the same rule as
68    /// [`insert`][VecSet::insert], [`extend`][Extend::extend], and
69    /// [`FromIterator`].
70    ///
71    /// **Note**: This conversion has a quadratic complexity because the
72    /// conversion preserves order of elements while at the same time having to
73    /// make sure no duplicate elements exist. To avoid it, sort and deduplicate
74    /// the vector and use [`VecSet::from_vec_unchecked`] instead.
75    fn from(mut vec: Vec<T>) -> Self {
76        crate::dedup_keep_first(&mut vec, |lhs, rhs| lhs == rhs);
77        // SAFETY: We've just deduplicated the elements.
78        unsafe { Self::from_vec_unchecked(vec) }
79    }
80}
81
82impl<T> From<&[T]> for VecSet<T>
83where
84    T: Clone + Eq,
85{
86    fn from(slice: &[T]) -> Self {
87        slice.iter().cloned().collect()
88    }
89}
90
91impl<T> From<&mut [T]> for VecSet<T>
92where
93    T: Clone + Eq,
94{
95    fn from(slice: &mut [T]) -> Self {
96        slice.iter().cloned().collect()
97    }
98}
99
100impl<T, const N: usize> From<[T; N]> for VecSet<T>
101where
102    T: Eq,
103{
104    fn from(arr: [T; N]) -> Self {
105        VecSet::from_iter(arr)
106    }
107}
108
109impl<T> PartialEq for VecSet<T>
110where
111    T: Eq,
112{
113    fn eq(&self, other: &VecSet<T>) -> bool {
114        self.base == other.base
115    }
116}
117
118impl<T> Eq for VecSet<T> where T: Eq {}
119
120impl<T> BitAnd<&VecSet<T>> for &VecSet<T>
121where
122    T: Eq + Clone,
123{
124    type Output = VecSet<T>;
125
126    /// Returns the set intersection, cloned into a new set.
127    ///
128    /// Values are collected in the same order that they appear in `self`.
129    fn bitand(self, other: &VecSet<T>) -> Self::Output {
130        self.intersection(other).cloned().collect()
131    }
132}
133
134impl<T> BitOr<&VecSet<T>> for &VecSet<T>
135where
136    T: Eq + Clone,
137{
138    type Output = VecSet<T>;
139
140    /// Returns the set union, cloned into a new set.
141    ///
142    /// Values from `self` are collected in their original order, followed by values that are
143    /// unique to `other` in their original order.
144    fn bitor(self, other: &VecSet<T>) -> Self::Output {
145        self.union(other).cloned().collect()
146    }
147}
148
149impl<T> BitXor<&VecSet<T>> for &VecSet<T>
150where
151    T: Eq + Clone,
152{
153    type Output = VecSet<T>;
154
155    /// Returns the set symmetric-difference, cloned into a new set.
156    ///
157    /// Values from `self` are collected in their original order, followed by values from `other`
158    /// in their original order.
159    fn bitxor(self, other: &VecSet<T>) -> Self::Output {
160        self.symmetric_difference(other).cloned().collect()
161    }
162}
163
164impl<T> Sub<&VecSet<T>> for &VecSet<T>
165where
166    T: Eq + Clone,
167{
168    type Output = VecSet<T>;
169
170    /// Returns the set difference, cloned into a new set.
171    ///
172    /// Values are collected in the same order that they appear in `self`.
173    fn sub(self, other: &VecSet<T>) -> Self::Output {
174        self.difference(other).cloned().collect()
175    }
176}
177
178#[cfg(test)]
179mod test {
180    use super::*;
181    extern crate alloc;
182    use alloc::vec;
183
184    #[derive(Clone, Debug)]
185    #[allow(dead_code)]
186    struct Item(i32, &'static str);
187
188    impl Eq for Item {}
189
190    impl PartialEq for Item {
191        fn eq(&self, other: &Self) -> bool {
192            self.0 == other.0
193        }
194    }
195
196    fn set_via_inserts(items: &[Item]) -> VecSet<Item> {
197        let mut set = VecSet::new();
198        for item in items {
199            set.insert(item.clone());
200        }
201        set
202    }
203
204    #[test]
205    fn constructor_parity_with_insert() {
206        let input = vec![Item(1, "first"), Item(2, "b"), Item(1, "second")];
207        let expected = set_via_inserts(&[Item(1, "first"), Item(2, "b"), Item(1, "second")]);
208
209        assert_eq!(VecSet::from(input.clone()), expected);
210        assert_eq!(input.into_iter().collect::<VecSet<_>>(), expected);
211        assert_eq!(
212            VecSet::from([Item(1, "first"), Item(2, "b"), Item(1, "second")]),
213            expected
214        );
215        assert_eq!(expected.as_slice(), &[Item(1, "first"), Item(2, "b")]);
216    }
217
218    #[test]
219    fn insert_rejects_duplicate_without_replacing() {
220        let mut set = VecSet::new();
221        assert!(set.insert(Item(1, "first")));
222        assert!(!set.insert(Item(1, "second")));
223        assert_eq!(set.as_slice(), &[Item(1, "first")]);
224    }
225
226    #[test]
227    fn extend_parity_with_insert() {
228        let mut via_extend = VecSet::new();
229        via_extend.extend([Item(1, "first"), Item(2, "b"), Item(1, "second")]);
230
231        let via_insert = set_via_inserts(&[Item(1, "first"), Item(2, "b"), Item(1, "second")]);
232        assert_eq!(via_extend, via_insert);
233    }
234
235    #[test]
236    fn append_parity_with_insert() {
237        let mut base = set_via_inserts(&[Item(1, "first")]);
238        let mut extra = VecSet::from(vec![Item(1, "second"), Item(2, "b")]);
239
240        base.append(&mut extra);
241
242        let expected = set_via_inserts(&[Item(1, "first"), Item(1, "second"), Item(2, "b")]);
243        assert_eq!(base, expected);
244        assert!(extra.is_empty());
245    }
246}