Skip to main content

bitflagset/
bitset.rs

1use core::hash::{Hash, Hasher};
2use core::marker::PhantomData;
3use core::ops::{Deref, DerefMut};
4use num_traits::{AsPrimitive, PrimInt, Zero};
5
6use super::slice::BitSlice;
7
8#[derive(Clone)]
9pub struct PrimBitSetIter<I: PrimInt, V>(pub I, pub PhantomData<V>);
10
11impl<I: PrimInt, V> PrimBitSetIter<I, V> {
12    #[inline]
13    pub const fn from_raw(raw: I) -> Self {
14        Self(raw, PhantomData)
15    }
16    #[inline]
17    pub fn empty() -> Self {
18        Self(I::zero(), PhantomData)
19    }
20    #[inline]
21    pub fn is_empty(&self) -> bool {
22        self.0.is_zero()
23    }
24    #[inline]
25    pub fn into_bits(&self) -> I {
26        self.0
27    }
28}
29
30impl<I, V> core::iter::Iterator for PrimBitSetIter<I, V>
31where
32    I: PrimInt + core::ops::BitAndAssign<I>,
33    V: TryFrom<u8>,
34{
35    type Item = V;
36
37    fn next(&mut self) -> Option<Self::Item> {
38        if self.0.is_zero() {
39            return None;
40        }
41        let idx = self.0.trailing_zeros();
42        self.0.bitand_assign(!(I::one().unsigned_shl(idx)));
43
44        let converted = V::try_from(idx as u8);
45        debug_assert!(converted.is_ok());
46        Some(converted.unwrap_or_else(|_| unsafe {
47            // SAFETY: bit index always fits in u8 (max 63 for u64)
48            core::hint::unreachable_unchecked()
49        }))
50    }
51}
52
53impl<I, V> core::iter::ExactSizeIterator for PrimBitSetIter<I, V>
54where
55    I: PrimInt + core::ops::BitAndAssign<I>,
56    V: TryFrom<u8>,
57{
58    #[inline]
59    fn len(&self) -> usize {
60        self.0.count_ones() as usize
61    }
62}
63
64impl<I: PrimInt + core::ops::BitAndAssign<I>, V: TryFrom<u8>> core::iter::FusedIterator
65    for PrimBitSetIter<I, V>
66{
67}
68
69// Sealed marker: only applies to single primitive stores.
70// Prevents coherence conflicts with [T; N].
71// Public but cannot be implemented externally (sealed).
72mod sealed {
73    pub trait PrimStore: num_traits::PrimInt {
74        const ZERO: Self;
75    }
76    impl PrimStore for u8 {
77        const ZERO: Self = 0;
78    }
79    impl PrimStore for u16 {
80        const ZERO: Self = 0;
81    }
82    impl PrimStore for u32 {
83        const ZERO: Self = 0;
84    }
85    impl PrimStore for u64 {
86        const ZERO: Self = 0;
87    }
88    impl PrimStore for u128 {
89        const ZERO: Self = 0;
90    }
91    impl PrimStore for usize {
92        const ZERO: Self = 0;
93    }
94}
95pub use sealed::PrimStore;
96
97#[repr(transparent)]
98#[derive(Clone, Copy)]
99pub struct BitSet<A, V>(pub(crate) A, pub(crate) PhantomData<V>);
100
101impl<A: PrimStore, V> Deref for BitSet<A, V> {
102    type Target = BitSlice<A, V>;
103
104    #[inline]
105    fn deref(&self) -> &Self::Target {
106        BitSlice::from_slice_ref(core::slice::from_ref(&self.0))
107    }
108}
109
110impl<A: PrimStore, V> DerefMut for BitSet<A, V> {
111    #[inline]
112    fn deref_mut(&mut self) -> &mut Self::Target {
113        BitSlice::from_slice_mut(core::slice::from_mut(&mut self.0))
114    }
115}
116
117impl<A: PrimStore + PartialEq, V> PartialEq for BitSet<A, V> {
118    fn eq(&self, other: &Self) -> bool {
119        self.0 == other.0
120    }
121}
122
123impl<A: PrimStore + Eq, V> Eq for BitSet<A, V> {}
124
125impl<A: PrimStore + Ord, V> PartialOrd for BitSet<A, V> {
126    #[inline]
127    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
128        Some(self.cmp(other))
129    }
130}
131
132impl<A: PrimStore + Ord, V> Ord for BitSet<A, V> {
133    #[inline]
134    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
135        self.0.cmp(&other.0)
136    }
137}
138
139impl<A: PrimStore + Hash, V> Hash for BitSet<A, V> {
140    fn hash<H: Hasher>(&self, state: &mut H) {
141        self.0.hash(state);
142    }
143}
144
145impl<A: PrimStore, V> core::fmt::Debug for BitSet<A, V> {
146    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
147        let mut formatter = f.debug_tuple("BitSet");
148        let bits = core::mem::size_of::<A>() * 8;
149        for idx in 0..bits {
150            if self.0 & A::one().unsigned_shl(idx as u32) != A::zero() {
151                formatter.field(&idx);
152            }
153        }
154        formatter.finish()
155    }
156}
157
158impl<A: PrimStore, V> BitSet<A, V> {
159    const ZERO: Self = Self(A::ZERO, PhantomData);
160    const BITS: usize = core::mem::size_of::<A>() * 8;
161
162    #[inline]
163    pub const fn new() -> Self {
164        Self::ZERO
165    }
166
167    #[inline]
168    pub fn from_element(elem: V) -> Self
169    where
170        V: AsPrimitive<usize>,
171    {
172        let mut ret = Self::new();
173        ret.set(elem, true);
174        ret
175    }
176
177    #[inline]
178    pub fn into_bits(self) -> A {
179        self.0
180    }
181
182    #[inline]
183    pub fn union(&self, other: &A) -> BitSet<A, V>
184    where
185        A: Copy + core::ops::BitOr<Output = A>,
186    {
187        BitSet(self.0 | *other, PhantomData)
188    }
189
190    #[inline]
191    pub fn difference(&self, other: &A) -> BitSet<A, V>
192    where
193        A: Copy + core::ops::BitAnd<Output = A> + core::ops::Not<Output = A>,
194    {
195        BitSet(self.0 & !*other, PhantomData)
196    }
197
198    #[inline]
199    pub fn includes(&self, other: &A) -> bool
200    where
201        A: Copy + core::ops::BitAnd<Output = A> + PartialEq,
202    {
203        self.0 & *other == *other
204    }
205
206    /// Snapshot iterator over set bit positions.
207    /// Copies the raw bits, so the bitset can be mutated while iterating.
208    #[inline]
209    pub fn iter(&self) -> PrimBitSetIter<A, V>
210    where
211        A: PrimInt,
212    {
213        PrimBitSetIter(self.0, PhantomData)
214    }
215
216    #[inline]
217    pub fn load_store(&self) -> A
218    where
219        A: Copy,
220    {
221        self.0
222    }
223
224    #[inline]
225    pub fn swap_store(&mut self, store: &mut A) {
226        core::mem::swap(&mut self.0, store);
227    }
228
229    #[inline]
230    pub fn mut_store(&mut self, f: impl Fn(&mut A)) {
231        f(&mut self.0);
232    }
233
234    #[inline]
235    pub fn drain(&mut self) -> PrimBitSetIter<A, V>
236    where
237        A: PrimInt + Zero,
238    {
239        let mut store = A::zero();
240        self.swap_store(&mut store);
241        PrimBitSetIter(store, PhantomData)
242    }
243
244    #[inline]
245    pub fn union_from(&mut self, other: A)
246    where
247        A: Copy + core::ops::BitOrAssign<A>,
248    {
249        self.0 |= other;
250    }
251
252    #[inline]
253    pub fn set(&mut self, id: V, value: bool)
254    where
255        V: AsPrimitive<usize>,
256    {
257        let idx = id.as_();
258        debug_assert!(
259            idx < Self::BITS,
260            "index {idx} out of range for capacity {}",
261            Self::BITS
262        );
263        if idx >= Self::BITS {
264            return;
265        }
266        let bit = A::one().unsigned_shl(idx as u32);
267        if value {
268            self.0 = self.0 | bit;
269        } else {
270            self.0 = self.0 & !bit;
271        }
272    }
273
274    #[inline]
275    pub fn insert(&mut self, id: V) -> bool
276    where
277        V: AsPrimitive<usize>,
278    {
279        let idx = id.as_();
280        debug_assert!(
281            idx < Self::BITS,
282            "index {idx} out of range for capacity {}",
283            Self::BITS
284        );
285        if idx >= Self::BITS {
286            return false;
287        }
288        let bit = A::one().unsigned_shl(idx as u32);
289        let was_absent = self.0 & bit == A::zero();
290        self.0 = self.0 | bit;
291        was_absent
292    }
293
294    #[inline]
295    pub fn remove(&mut self, id: V) -> bool
296    where
297        V: AsPrimitive<usize>,
298    {
299        let idx = id.as_();
300        debug_assert!(
301            idx < Self::BITS,
302            "index {idx} out of range for capacity {}",
303            Self::BITS
304        );
305        if idx >= Self::BITS {
306            return false;
307        }
308        let bit = A::one().unsigned_shl(idx as u32);
309        let was_present = self.0 & bit != A::zero();
310        self.0 = self.0 & !bit;
311        was_present
312    }
313
314    #[inline]
315    pub fn toggle(&mut self, id: V)
316    where
317        V: AsPrimitive<usize>,
318    {
319        let idx = id.as_();
320        debug_assert!(
321            idx < Self::BITS,
322            "index {idx} out of range for capacity {}",
323            Self::BITS
324        );
325        if idx >= Self::BITS {
326            return;
327        }
328        self.0 = self.0 ^ A::one().unsigned_shl(idx as u32);
329    }
330
331    #[cfg(feature = "bitvec")]
332    #[inline]
333    pub fn as_bitvec_array(&self) -> &bitvec::array::BitArray<A>
334    where
335        A: bitvec::store::BitStore + bitvec::view::BitViewSized,
336    {
337        // SAFETY: BitArray<A> is #[repr(transparent)] over A
338        unsafe { &*(&self.0 as *const A as *const bitvec::array::BitArray<A>) }
339    }
340
341    #[cfg(feature = "bitvec")]
342    #[inline]
343    pub fn into_bitvec_array(self) -> bitvec::array::BitArray<A>
344    where
345        A: bitvec::store::BitStore + bitvec::view::BitViewSized,
346    {
347        bitvec::array::BitArray::new(self.0)
348    }
349}
350
351impl<A: PrimStore, V> core::iter::IntoIterator for BitSet<A, V>
352where
353    A: PrimInt + core::ops::BitAndAssign<A>,
354    V: TryFrom<u8>,
355{
356    type Item = V;
357    type IntoIter = PrimBitSetIter<A, V>;
358
359    fn into_iter(self) -> Self::IntoIter {
360        PrimBitSetIter(self.0, PhantomData)
361    }
362}
363
364impl<'a, A: PrimStore + core::ops::BitAndAssign, V: TryFrom<usize>> IntoIterator
365    for &'a BitSet<A, V>
366{
367    type Item = V;
368    type IntoIter = super::slice::BitSliceIter<'a, A, V>;
369
370    #[inline]
371    fn into_iter(self) -> Self::IntoIter {
372        (**self).iter()
373    }
374}
375
376impl<A: PrimStore, V> Default for BitSet<A, V> {
377    #[inline]
378    fn default() -> Self {
379        Self::new()
380    }
381}
382
383impl<A: Copy + PrimStore, V: AsPrimitive<usize>> FromIterator<V> for BitSet<A, V> {
384    fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
385        let mut ret = Self::new();
386
387        for item in iter {
388            ret.set(item, true);
389        }
390
391        ret
392    }
393}
394
395impl<A: Copy + PrimStore, V: AsPrimitive<usize>> core::iter::Extend<V> for BitSet<A, V> {
396    fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
397        for item in iter {
398            self.set(item, true);
399        }
400    }
401}
402
403impl<A: PrimStore + core::ops::BitOrAssign + Copy, V> FromIterator<BitSet<A, V>> for BitSet<A, V> {
404    fn from_iter<I: IntoIterator<Item = Self>>(iter: I) -> Self {
405        let mut ret = Self::new();
406        for bs in iter {
407            ret.0 |= bs.0;
408        }
409        ret
410    }
411}
412
413impl<A: PrimStore + core::ops::BitOrAssign + Copy, V> core::iter::Extend<BitSet<A, V>>
414    for BitSet<A, V>
415{
416    fn extend<I: IntoIterator<Item = Self>>(&mut self, iter: I) {
417        for bs in iter {
418            self.0 |= bs.0;
419        }
420    }
421}
422
423impl<A: PrimStore + core::fmt::Binary, V> core::fmt::Binary for BitSet<A, V> {
424    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
425        core::fmt::Binary::fmt(&self.0, f)
426    }
427}
428
429impl<A: PrimStore + core::fmt::Octal, V> core::fmt::Octal for BitSet<A, V> {
430    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
431        core::fmt::Octal::fmt(&self.0, f)
432    }
433}
434
435impl<A: PrimStore + core::fmt::LowerHex, V> core::fmt::LowerHex for BitSet<A, V> {
436    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
437        core::fmt::LowerHex::fmt(&self.0, f)
438    }
439}
440
441impl<A: PrimStore + core::fmt::UpperHex, V> core::fmt::UpperHex for BitSet<A, V> {
442    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
443        core::fmt::UpperHex::fmt(&self.0, f)
444    }
445}
446
447#[cfg(feature = "bitvec")]
448impl<A, V> From<bitvec::array::BitArray<A>> for BitSet<A, V>
449where
450    A: PrimStore + bitvec::store::BitStore + bitvec::view::BitViewSized,
451{
452    #[inline]
453    fn from(arr: bitvec::array::BitArray<A>) -> Self {
454        Self(arr.into_inner(), PhantomData)
455    }
456}
457
458#[cfg(feature = "bitvec")]
459impl<A, V> From<BitSet<A, V>> for bitvec::array::BitArray<A>
460where
461    A: PrimStore + bitvec::store::BitStore + bitvec::view::BitViewSized,
462{
463    #[inline]
464    fn from(bs: BitSet<A, V>) -> Self {
465        bitvec::array::BitArray::new(bs.0)
466    }
467}
468
469macro_rules! impl_bitset_const {
470    ($($ty:ty),+) => {$(
471        impl<V> BitSet<$ty, V> {
472            /// Const constructor from raw bits.
473            #[inline]
474            pub const fn from_bits(raw: $ty) -> Self {
475                Self(raw, PhantomData)
476            }
477
478            /// Raw bits accessor (const).
479            #[inline]
480            pub const fn bits(&self) -> $ty {
481                self.0
482            }
483
484            /// Const constructor from a single bit index.
485            #[inline]
486            pub const fn from_index(idx: usize) -> Self {
487                Self::from_bits((1 as $ty) << idx)
488            }
489
490            /// Const constructor from a slice of bit indices.
491            #[inline]
492            pub const fn from_indices(indices: &[usize]) -> Self {
493                let mut raw: $ty = 0;
494                let mut i = 0;
495                while i < indices.len() {
496                    raw |= (1 as $ty) << indices[i];
497                    i += 1;
498                }
499                Self::from_bits(raw)
500            }
501
502            #[inline]
503            pub const fn len(&self) -> usize {
504                self.0.count_ones() as usize
505            }
506
507            #[inline]
508            pub const fn is_empty(&self) -> bool {
509                self.0 == 0
510            }
511
512            /// Const bit-index membership test.
513            #[inline]
514            pub const fn contains(&self, idx: &usize) -> bool {
515                self.0 & ((1 as $ty) << *idx) != 0
516            }
517
518            #[inline]
519            pub const fn is_subset(&self, other: &Self) -> bool {
520                self.0 & other.0 == self.0
521            }
522
523            #[inline]
524            pub const fn is_superset(&self, other: &Self) -> bool {
525                self.0 & other.0 == other.0
526            }
527
528            #[inline]
529            pub const fn is_disjoint(&self, other: &Self) -> bool {
530                self.0 & other.0 == 0
531            }
532        }
533    )+};
534}
535impl_bitset_const!(u8, u16, u32, u64, u128, usize);
536
537impl<A: PrimStore + Copy + core::ops::BitOr<Output = A>, V> core::ops::BitOr for BitSet<A, V> {
538    type Output = Self;
539    #[inline]
540    fn bitor(self, rhs: Self) -> Self {
541        Self(self.0 | rhs.0, PhantomData)
542    }
543}
544
545impl<A: PrimStore + core::ops::BitOrAssign, V> core::ops::BitOrAssign for BitSet<A, V> {
546    #[inline]
547    fn bitor_assign(&mut self, rhs: Self) {
548        self.0 |= rhs.0;
549    }
550}
551
552impl<A: PrimStore + Copy + core::ops::BitAnd<Output = A>, V> core::ops::BitAnd for BitSet<A, V> {
553    type Output = Self;
554    #[inline]
555    fn bitand(self, rhs: Self) -> Self {
556        Self(self.0 & rhs.0, PhantomData)
557    }
558}
559
560impl<A: PrimStore + core::ops::BitAndAssign, V> core::ops::BitAndAssign for BitSet<A, V> {
561    #[inline]
562    fn bitand_assign(&mut self, rhs: Self) {
563        self.0 &= rhs.0;
564    }
565}
566
567impl<A: PrimStore + Copy + core::ops::BitXor<Output = A>, V> core::ops::BitXor for BitSet<A, V> {
568    type Output = Self;
569    #[inline]
570    fn bitxor(self, rhs: Self) -> Self {
571        Self(self.0 ^ rhs.0, PhantomData)
572    }
573}
574
575impl<A: PrimStore + core::ops::BitXorAssign, V> core::ops::BitXorAssign for BitSet<A, V> {
576    #[inline]
577    fn bitxor_assign(&mut self, rhs: Self) {
578        self.0 ^= rhs.0;
579    }
580}
581
582impl<A: PrimStore + Copy + core::ops::Not<Output = A>, V> core::ops::Not for BitSet<A, V> {
583    type Output = Self;
584    #[inline]
585    fn not(self) -> Self {
586        Self(!self.0, PhantomData)
587    }
588}
589
590impl<A, V> core::ops::Sub for BitSet<A, V>
591where
592    A: PrimStore + Copy + core::ops::BitAnd<Output = A> + core::ops::Not<Output = A>,
593{
594    type Output = Self;
595    #[inline]
596    fn sub(self, rhs: Self) -> Self {
597        Self(self.0 & !rhs.0, PhantomData)
598    }
599}
600
601impl<A, V> core::ops::SubAssign for BitSet<A, V>
602where
603    A: PrimStore + Copy + core::ops::BitAndAssign + core::ops::Not<Output = A>,
604{
605    #[inline]
606    fn sub_assign(&mut self, rhs: Self) {
607        self.0 &= !rhs.0;
608    }
609}
610
611/// Backward-compatible alias: `ArrayBitSet<A, V, N>` = `BitSet<[A; N], V>`
612pub type ArrayBitSet<A, V, const N: usize> = BitSet<[A; N], V>;
613
614// [T; N] arrays — Provide array-specific methods in a separate impl block.
615
616impl<T, V, const N: usize> Deref for BitSet<[T; N], V> {
617    type Target = BitSlice<T, V>;
618
619    #[inline]
620    fn deref(&self) -> &Self::Target {
621        BitSlice::from_slice_ref(&self.0)
622    }
623}
624
625impl<T, V, const N: usize> DerefMut for BitSet<[T; N], V> {
626    #[inline]
627    fn deref_mut(&mut self) -> &mut Self::Target {
628        BitSlice::from_slice_mut(&mut self.0)
629    }
630}
631
632impl<T: PrimStore, V, const N: usize> BitSet<[T; N], V> {
633    const ZERO: Self = Self([T::ZERO; N], PhantomData);
634
635    #[inline]
636    pub const fn new() -> Self {
637        Self::ZERO
638    }
639
640    #[inline]
641    pub const fn empty() -> Self {
642        Self::new()
643    }
644
645    #[inline]
646    pub fn from_bits(raw: [T; N]) -> Self {
647        Self(raw, PhantomData)
648    }
649
650    #[inline]
651    pub fn from_element(id: V) -> Self
652    where
653        T: PrimInt,
654        V: AsPrimitive<usize>,
655    {
656        let mut zelf = Self::new();
657        zelf.set(id, true);
658        zelf
659    }
660
661    #[inline]
662    pub fn into_bits(self) -> [T; N] {
663        self.0
664    }
665
666    #[inline]
667    pub fn is_subset(&self, other: &Self) -> bool
668    where
669        T: Copy + core::ops::BitAnd<Output = T> + PartialEq,
670    {
671        self.0
672            .iter()
673            .zip(other.0.iter())
674            .all(|(a, b)| *a & *b == *a)
675    }
676
677    #[inline]
678    pub fn is_superset(&self, other: &Self) -> bool
679    where
680        T: Copy + core::ops::BitAnd<Output = T> + PartialEq,
681    {
682        other.is_subset(self)
683    }
684
685    #[inline]
686    pub fn is_disjoint(&self, other: &Self) -> bool
687    where
688        T: Copy + core::ops::BitAnd<Output = T> + num_traits::Zero,
689    {
690        self.0
691            .iter()
692            .zip(other.0.iter())
693            .all(|(a, b)| (*a & *b).is_zero())
694    }
695
696    #[inline]
697    pub fn as_slice(&self) -> &[T] {
698        self.0.as_ref()
699    }
700
701    #[inline]
702    pub fn as_mut_slice(&mut self) -> &mut [T] {
703        self.0.as_mut()
704    }
705
706    #[cfg(feature = "bitvec")]
707    #[inline]
708    pub fn as_bitvec_array(&self) -> &bitvec::array::BitArray<[T; N]>
709    where
710        T: bitvec::store::BitStore,
711        [T; N]: bitvec::view::BitViewSized,
712    {
713        // SAFETY: BitArray<[T; N]> is #[repr(transparent)] over [T; N]
714        unsafe { &*(&self.0 as *const [T; N] as *const bitvec::array::BitArray<[T; N]>) }
715    }
716
717    #[cfg(feature = "bitvec")]
718    #[inline]
719    pub fn into_bitvec_array(self) -> bitvec::array::BitArray<[T; N]>
720    where
721        T: bitvec::store::BitStore,
722        [T; N]: bitvec::view::BitViewSized,
723    {
724        bitvec::array::BitArray::new(self.0)
725    }
726}
727
728#[cfg(feature = "bitvec")]
729impl<T, V, const N: usize> From<bitvec::array::BitArray<[T; N]>> for BitSet<[T; N], V>
730where
731    T: bitvec::store::BitStore,
732    [T; N]: bitvec::view::BitViewSized,
733{
734    #[inline]
735    fn from(arr: bitvec::array::BitArray<[T; N]>) -> Self {
736        Self(arr.into_inner(), PhantomData)
737    }
738}
739
740#[cfg(feature = "bitvec")]
741impl<T, V, const N: usize> From<BitSet<[T; N], V>> for bitvec::array::BitArray<[T; N]>
742where
743    T: bitvec::store::BitStore,
744    [T; N]: bitvec::view::BitViewSized,
745{
746    #[inline]
747    fn from(bs: BitSet<[T; N], V>) -> Self {
748        bitvec::array::BitArray::new(bs.0)
749    }
750}
751
752impl<T: PartialEq, V, const N: usize> PartialEq for BitSet<[T; N], V> {
753    fn eq(&self, other: &Self) -> bool {
754        self.0 == other.0
755    }
756}
757
758impl<T: Eq, V, const N: usize> Eq for BitSet<[T; N], V> {}
759
760impl<T: Hash, V, const N: usize> Hash for BitSet<[T; N], V> {
761    fn hash<H: Hasher>(&self, state: &mut H) {
762        self.0.hash(state);
763    }
764}
765
766impl<T: PrimInt, V, const N: usize> core::fmt::Debug for BitSet<[T; N], V> {
767    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
768        let mut formatter = f.debug_tuple("BitSet");
769        let bits_per = core::mem::size_of::<T>() * 8;
770        for (seg_idx, &word) in self.0.iter().enumerate() {
771            for bit in 0..bits_per {
772                if word & T::one().unsigned_shl(bit as u32) != T::zero() {
773                    formatter.field(&(seg_idx * bits_per + bit));
774                }
775            }
776        }
777        formatter.finish()
778    }
779}
780
781impl<T: PrimStore, V, const N: usize> Default for BitSet<[T; N], V> {
782    #[inline]
783    fn default() -> Self {
784        Self::new()
785    }
786}
787
788impl<T, V, const N: usize> core::ops::BitOr for BitSet<[T; N], V>
789where
790    T: PrimStore + core::ops::BitOr<Output = T> + Copy,
791{
792    type Output = Self;
793    #[inline]
794    fn bitor(self, rhs: Self) -> Self {
795        Self::from_bits(core::array::from_fn(|i| self.0[i] | rhs.0[i]))
796    }
797}
798
799impl<T, V, const N: usize> core::ops::BitOrAssign for BitSet<[T; N], V>
800where
801    T: PrimStore + core::ops::BitOrAssign + Copy,
802{
803    #[inline]
804    fn bitor_assign(&mut self, rhs: Self) {
805        for i in 0..N {
806            self.0[i] |= rhs.0[i];
807        }
808    }
809}
810
811impl<T, V, const N: usize> core::ops::BitAnd for BitSet<[T; N], V>
812where
813    T: PrimStore + core::ops::BitAnd<Output = T> + Copy,
814{
815    type Output = Self;
816    #[inline]
817    fn bitand(self, rhs: Self) -> Self {
818        Self::from_bits(core::array::from_fn(|i| self.0[i] & rhs.0[i]))
819    }
820}
821
822impl<T, V, const N: usize> core::ops::BitAndAssign for BitSet<[T; N], V>
823where
824    T: PrimStore + core::ops::BitAndAssign + Copy,
825{
826    #[inline]
827    fn bitand_assign(&mut self, rhs: Self) {
828        for i in 0..N {
829            self.0[i] &= rhs.0[i];
830        }
831    }
832}
833
834impl<T, V, const N: usize> core::ops::BitXor for BitSet<[T; N], V>
835where
836    T: PrimStore + core::ops::BitXor<Output = T> + Copy,
837{
838    type Output = Self;
839    #[inline]
840    fn bitxor(self, rhs: Self) -> Self {
841        Self::from_bits(core::array::from_fn(|i| self.0[i] ^ rhs.0[i]))
842    }
843}
844
845impl<T, V, const N: usize> core::ops::BitXorAssign for BitSet<[T; N], V>
846where
847    T: PrimStore + core::ops::BitXorAssign + Copy,
848{
849    #[inline]
850    fn bitxor_assign(&mut self, rhs: Self) {
851        for i in 0..N {
852            self.0[i] ^= rhs.0[i];
853        }
854    }
855}
856
857impl<T, V, const N: usize> core::ops::Not for BitSet<[T; N], V>
858where
859    T: PrimStore + core::ops::Not<Output = T> + Copy,
860{
861    type Output = Self;
862    #[inline]
863    fn not(self) -> Self {
864        Self::from_bits(core::array::from_fn(|i| !self.0[i]))
865    }
866}
867
868impl<T, V, const N: usize> core::ops::Sub for BitSet<[T; N], V>
869where
870    T: PrimStore + core::ops::BitAnd<Output = T> + core::ops::Not<Output = T> + Copy,
871{
872    type Output = Self;
873    #[inline]
874    fn sub(self, rhs: Self) -> Self {
875        Self::from_bits(core::array::from_fn(|i| self.0[i] & !rhs.0[i]))
876    }
877}
878
879impl<T, V, const N: usize> core::ops::SubAssign for BitSet<[T; N], V>
880where
881    T: PrimStore + Copy + core::ops::Not<Output = T> + core::ops::BitAndAssign,
882{
883    #[inline]
884    fn sub_assign(&mut self, rhs: Self) {
885        for i in 0..N {
886            self.0[i] &= !rhs.0[i];
887        }
888    }
889}
890
891impl<'a, T: PrimInt + core::ops::BitAndAssign, V: TryFrom<usize>, const N: usize> IntoIterator
892    for &'a BitSet<[T; N], V>
893{
894    type Item = V;
895    type IntoIter = super::slice::BitSliceIter<'a, T, V>;
896
897    #[inline]
898    fn into_iter(self) -> Self::IntoIter {
899        self.iter()
900    }
901}
902
903impl<T: PrimStore, V: AsPrimitive<usize>, const N: usize> core::iter::Extend<V>
904    for BitSet<[T; N], V>
905{
906    fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
907        for item in iter {
908            self.set(item, true);
909        }
910    }
911}
912
913impl<T: PrimStore, V: AsPrimitive<usize>, const N: usize> FromIterator<V> for BitSet<[T; N], V> {
914    fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
915        let mut ret = Self::new();
916        for item in iter {
917            ret.set(item, true);
918        }
919        ret
920    }
921}
922
923impl<T: PrimStore + core::ops::BitOrAssign + Copy, V, const N: usize>
924    FromIterator<BitSet<[T; N], V>> for BitSet<[T; N], V>
925{
926    fn from_iter<I: IntoIterator<Item = Self>>(iter: I) -> Self {
927        let mut ret = Self::new();
928        for bs in iter {
929            for i in 0..N {
930                ret.0[i] |= bs.0[i];
931            }
932        }
933        ret
934    }
935}
936
937impl<T: PrimStore + core::ops::BitOrAssign + Copy, V, const N: usize>
938    core::iter::Extend<BitSet<[T; N], V>> for BitSet<[T; N], V>
939{
940    fn extend<I: IntoIterator<Item = Self>>(&mut self, iter: I) {
941        for bs in iter {
942            for i in 0..N {
943                self.0[i] |= bs.0[i];
944            }
945        }
946    }
947}
948
949#[cfg(test)]
950mod tests {
951    use super::*;
952    use alloc::vec;
953    use alloc::vec::Vec;
954    use proptest::prelude::*;
955    use rand::Rng;
956
957    #[test]
958    fn test_size_prim() {
959        assert_eq!(
960            core::mem::size_of::<BitSet<u64, i32>>(),
961            core::mem::size_of::<u64>()
962        );
963        assert_eq!(
964            core::mem::size_of::<BitSet<u32, i32>>(),
965            core::mem::size_of::<u32>()
966        );
967        assert_eq!(
968            core::mem::size_of::<BitSet<u8, i32>>(),
969            core::mem::size_of::<u8>()
970        );
971    }
972
973    const SET: BitSet<u64, usize> = BitSet::<u64, usize>::from_indices(&[3, 7, 42]);
974    const RAW: BitSet<u64, usize> = BitSet::<u64, usize>::from_bits(0b1010);
975    const SINGLE: BitSet<u64, usize> = BitSet::<u64, usize>::from_index(5);
976    const EMPTY: BitSet<u64, usize> = BitSet::<u64, usize>::new();
977
978    // from_bits / bits
979    const _: () = assert!(RAW.bits() == 0b1010);
980
981    // from_indices / from_index
982    const _: () = assert!(SET.contains(&3));
983    const _: () = assert!(SET.contains(&7));
984    const _: () = assert!(SET.contains(&42));
985    const _: () = assert!(!SET.contains(&0));
986    const _: () = assert!(SINGLE.contains(&5));
987    const _: () = assert!(!SINGLE.contains(&4));
988
989    // len / is_empty
990    const _: () = assert!(SET.len() == 3);
991    const _: () = assert!(RAW.len() == 2);
992    const _: () = assert!(SINGLE.len() == 1);
993    const _: () = assert!(EMPTY.is_empty());
994    const _: () = assert!(!SET.is_empty());
995    const _: () = assert!(EMPTY.is_empty());
996
997    // is_subset / is_superset / is_disjoint
998    const SUPERSET: BitSet<u64, usize> = BitSet::<u64, usize>::from_indices(&[3, 7, 42, 50]);
999    const DISJOINT: BitSet<u64, usize> = BitSet::<u64, usize>::from_indices(&[0, 1]);
1000    const _: () = assert!(SET.is_subset(&SUPERSET));
1001    const _: () = assert!(!SUPERSET.is_subset(&SET));
1002    const _: () = assert!(SUPERSET.is_superset(&SET));
1003    const _: () = assert!(!SET.is_superset(&SUPERSET));
1004    const _: () = assert!(SET.is_disjoint(&DISJOINT));
1005    const _: () = assert!(!SET.is_disjoint(&SUPERSET));
1006    const _: () = assert!(EMPTY.is_disjoint(&SET));
1007
1008    // ── Runtime verification (same methods, non‐const path) ─
1009
1010    #[test]
1011    fn test_prim_const_methods_at_runtime() {
1012        // from_bits / bits roundtrip
1013        let bs = BitSet::<u64, usize>::from_bits(0xDEAD);
1014        assert_eq!(bs.bits(), 0xDEAD);
1015
1016        // from_index / from_indices
1017        let single = BitSet::<u32, usize>::from_index(10);
1018        assert!(single.contains(&10));
1019        assert_eq!(single.len(), 1);
1020
1021        let multi = BitSet::<u32, usize>::from_indices(&[1, 5, 9]);
1022        assert!(multi.contains(&1));
1023        assert!(multi.contains(&5));
1024        assert!(multi.contains(&9));
1025        assert!(!multi.contains(&2));
1026        assert_eq!(multi.len(), 3);
1027
1028        // is_empty
1029        assert!(BitSet::<u64, usize>::new().is_empty());
1030        assert!(!multi.is_empty());
1031
1032        // is_subset / is_superset / is_disjoint
1033        let superset = BitSet::<u32, usize>::from_indices(&[1, 5, 9, 20]);
1034        let disjoint = BitSet::<u32, usize>::from_indices(&[2, 3]);
1035        assert!(multi.is_subset(&superset));
1036        assert!(!superset.is_subset(&multi));
1037        assert!(superset.is_superset(&multi));
1038        assert!(multi.is_disjoint(&disjoint));
1039        assert!(!multi.is_disjoint(&superset));
1040    }
1041
1042    #[test]
1043    fn test_prim_deref_methods() {
1044        let mut bs = BitSet::<u64, usize>::new();
1045        bs.insert(3);
1046        bs.insert(7);
1047        bs.insert(42);
1048
1049        // BitSlice::contains (takes &V, generic)
1050        assert!(bs.contains(&3));
1051        assert!(bs.contains(&7));
1052        assert!(!bs.contains(&0));
1053
1054        // BitSlice::remove
1055        assert!(bs.remove(7));
1056        assert!(!bs.contains(&7));
1057
1058        // BitSlice::iter
1059        let items: Vec<usize> = bs.iter().collect();
1060        assert!(items.contains(&3));
1061        assert!(items.contains(&42));
1062
1063        // BitSlice::clear
1064        bs.clear();
1065        assert!(bs.is_empty());
1066    }
1067
1068    #[test]
1069    fn test_bitflagset() {
1070        use crate::BitFlagSet;
1071
1072        crate::bitflag! {
1073            #[derive(Debug)]
1074            #[repr(u8)]
1075            enum Color {
1076                Red = 0,
1077                Green = 1,
1078                Blue = 2,
1079            }
1080        }
1081
1082        crate::bitflagset!(struct ColorSet(u8) : Color);
1083
1084        // inherent method calls
1085        let set = ColorSet::from_element(Color::Green);
1086        assert_eq!(set.first(), Some(Color::Green));
1087        assert_eq!(set.last(), Some(Color::Green));
1088        assert_eq!(set.len(), 1);
1089        assert!(!set.is_empty());
1090        assert!(set.contains(&Color::Green));
1091        assert!(!set.contains(&Color::Red));
1092        let v: Vec<Color> = set.iter().collect();
1093        assert_eq!(v, vec![Color::Green]);
1094        assert_eq!(set.to_vec(), vec![Color::Green]);
1095
1096        // trait method calls
1097        let set2 = <ColorSet as BitFlagSet<Color, u8>>::from_element(Color::Blue);
1098        assert_eq!(BitFlagSet::first(&set2), Some(Color::Blue));
1099        assert_eq!(BitFlagSet::last(&set2), Some(Color::Blue));
1100        assert_eq!(BitFlagSet::len(&set2), 1);
1101        assert!(!BitFlagSet::is_empty(&set2));
1102        assert!(BitFlagSet::contains(&set2, &Color::Blue));
1103        let v2: Vec<Color> = BitFlagSet::iter(&set2).collect();
1104        assert_eq!(v2, vec![Color::Blue]);
1105        assert_eq!(BitFlagSet::to_vec(&set2), vec![Color::Blue]);
1106
1107        // insert / remove
1108        let mut set3 = ColorSet::empty();
1109        assert!(set3.insert(Color::Red));
1110        assert!(!set3.insert(Color::Red)); // already present
1111        assert!(set3.contains(&Color::Red));
1112        assert!(set3.remove(Color::Red));
1113        assert!(!set3.remove(Color::Red)); // already absent
1114        assert!(!set3.contains(&Color::Red));
1115
1116        // is_subset / is_superset / is_disjoint
1117        let rgb = ColorSet::from_slice(&[Color::Red, Color::Green, Color::Blue]);
1118        let rg = ColorSet::from_slice(&[Color::Red, Color::Green]);
1119        let b = ColorSet::from_element(Color::Blue);
1120        assert!(rg.is_subset(&rgb));
1121        assert!(!rgb.is_subset(&rg));
1122        assert!(rgb.is_superset(&rg));
1123        assert!(!rg.is_superset(&rgb));
1124        assert!(rg.is_disjoint(&b));
1125        assert!(!rg.is_disjoint(&rgb));
1126
1127        // BitXor (symmetric difference)
1128        let xor = rgb ^ rg;
1129        assert_eq!(xor, b);
1130        let mut xor_assign = rgb;
1131        xor_assign ^= rg;
1132        assert_eq!(xor_assign, b);
1133
1134        // Not (complement)
1135        let not_empty = !ColorSet::empty();
1136        assert!(not_empty.contains(&Color::Red));
1137        assert!(not_empty.contains(&Color::Green));
1138        assert!(not_empty.contains(&Color::Blue));
1139
1140        // Extend
1141        let mut set4 = ColorSet::empty();
1142        set4.extend([Color::Red, Color::Blue]);
1143        assert_eq!(set4.len(), 2);
1144        assert!(set4.contains(&Color::Red));
1145        assert!(set4.contains(&Color::Blue));
1146
1147        // compound operations
1148        let combined = set | set2;
1149        assert_eq!(combined.len(), 2);
1150        assert_eq!(combined.first(), Some(Color::Green));
1151        assert_eq!(combined.last(), Some(Color::Blue));
1152
1153        // From conversions
1154        let bs: BitSet<u8, Color> = rgb.into();
1155        assert_eq!(bs.len(), 3);
1156        let back: ColorSet = bs.into();
1157        assert_eq!(back, rgb);
1158
1159        // Additional inherent API coverage
1160        assert!(ColorSet::from_bits(0b111).is_some());
1161        assert_eq!(ColorSet::from_bits_truncate(0xFF), ColorSet::all());
1162        let unchecked = unsafe { ColorSet::from_bits_unchecked(0b001) };
1163        assert!(unchecked.contains(&Color::Red));
1164        let mut all = ColorSet::all();
1165        assert!(all.is_all());
1166        all.set(Color::Blue, false);
1167        all.toggle(Color::Blue);
1168        all.clear();
1169        assert!(all.is_empty());
1170        let _ = ColorSet::from_slice(&[Color::Red]).iter_names().count();
1171    }
1172
1173    prop_compose! {
1174        fn arb_indexes(bits: usize)(size in 0..100usize) -> Vec<usize> {
1175            let mut rng = rand::thread_rng();
1176            (0..size).map(|_| rng.gen_range(0..bits)).collect()
1177        }
1178    }
1179
1180    fn assert_set_result<I: PrimInt + core::ops::BitAndAssign<I>>(
1181        expected: &[usize],
1182        actual: PrimBitSetIter<I, usize>,
1183    ) {
1184        let mut expected = expected.to_vec();
1185        expected.sort_unstable();
1186        expected.dedup();
1187        let actual: Vec<_> = actual.collect();
1188        assert_eq!(expected, actual);
1189    }
1190
1191    proptest! {
1192        #[test]
1193        fn flag_set_iter_32(indexes in arb_indexes(32)) {
1194            let mut flags = BitSet::<u32, usize>::new();
1195            for idx in indexes.iter() {
1196                flags.set(*idx, true);
1197            }
1198            assert_set_result(&indexes, flags.drain());
1199        }
1200        #[test]
1201        fn flag_set_iter_64(indexes in arb_indexes(64)) {
1202            let mut flags = BitSet::<u64, usize>::new();
1203            for idx in indexes.iter() {
1204                flags.set(*idx, true);
1205            }
1206            assert_set_result(&indexes, flags.drain());
1207        }
1208
1209        #[test]
1210        fn parity_bitarray_128(ops in prop::collection::vec((any::<bool>(), 0..128usize), 0..200)) {
1211            use bitvec::array::BitArray;
1212            use bitvec::order::Lsb0;
1213
1214            let mut ours = BitSet::<[u64; 2], usize>::new();
1215            let mut bv = BitArray::<[u64; 2], Lsb0>::ZERO;
1216
1217            for &(insert, idx) in &ops {
1218                if insert {
1219                    ours.insert(idx);
1220                    bv.set(idx, true);
1221                } else {
1222                    ours.remove(idx);
1223                    bv.set(idx, false);
1224                }
1225            }
1226
1227            prop_assert_eq!(ours.len(), bv.count_ones(), "len mismatch");
1228            prop_assert_eq!(ours.is_empty(), bv.not_any(), "is_empty mismatch");
1229
1230            for i in 0..128 {
1231                prop_assert_eq!(ours.contains(&i), bv[i], "contains mismatch at {}", i);
1232            }
1233
1234            let ours_bits: Vec<usize> = ours.iter().collect();
1235            let bv_bits: Vec<usize> = bv.iter_ones().collect();
1236            prop_assert_eq!(ours_bits, bv_bits, "iter mismatch");
1237        }
1238
1239        #[test]
1240        fn parity_bitarray_1024(ops in prop::collection::vec((any::<bool>(), 0..1024usize), 0..200)) {
1241            use bitvec::array::BitArray;
1242            use bitvec::order::Lsb0;
1243
1244            let mut ours = BitSet::<[u64; 16], usize>::new();
1245            let mut bv = BitArray::<[u64; 16], Lsb0>::ZERO;
1246
1247            for &(insert, idx) in &ops {
1248                if insert {
1249                    ours.insert(idx);
1250                    bv.set(idx, true);
1251                } else {
1252                    ours.remove(idx);
1253                    bv.set(idx, false);
1254                }
1255            }
1256
1257            prop_assert_eq!(ours.len(), bv.count_ones(), "len mismatch");
1258            prop_assert_eq!(ours.is_empty(), bv.not_any(), "is_empty mismatch");
1259
1260            for i in 0..1024 {
1261                prop_assert_eq!(ours.contains(&i), bv[i], "contains mismatch at {}", i);
1262            }
1263
1264            let ours_bits: Vec<usize> = ours.iter().collect();
1265            let bv_bits: Vec<usize> = bv.iter_ones().collect();
1266            prop_assert_eq!(ours_bits, bv_bits, "iter mismatch");
1267        }
1268    }
1269
1270    #[test]
1271    fn test_size_array() {
1272        assert_eq!(
1273            core::mem::size_of::<BitSet<[u64; 11], i32>>(),
1274            core::mem::size_of::<[u64; 11]>()
1275        );
1276    }
1277
1278    #[test]
1279    fn test_basic() {
1280        let mut bs = BitSet::<[u64; 2], usize>::new();
1281        assert!(bs.is_empty());
1282        bs.set(0, true);
1283        bs.set(63, true);
1284        bs.set(64, true);
1285        bs.set(127, true);
1286        assert!(!bs.is_empty());
1287
1288        let items: Vec<usize> = bs.iter().collect();
1289        assert_eq!(items, vec![0, 63, 64, 127]);
1290    }
1291
1292    #[test]
1293    fn test_array_boundary_values() {
1294        // [u64; 4] = 256 bits, max index = 255
1295        let mut bs = BitSet::<[u64; 4], usize>::new();
1296        bs.insert(0);
1297        bs.insert(255);
1298        assert_eq!(bs.len(), 2);
1299        assert!(bs.contains(&0));
1300        assert!(bs.contains(&255));
1301        assert!(!bs.contains(&1));
1302        assert!(!bs.contains(&254));
1303
1304        let items: Vec<usize> = bs.iter().collect();
1305        assert_eq!(items, vec![0, 255]);
1306
1307        assert!(bs.remove(255));
1308        assert!(!bs.contains(&255));
1309        assert_eq!(bs.len(), 1);
1310
1311        // [u64; 16] = 1024 bits, max index = 1023
1312        let mut bs = BitSet::<[u64; 16], usize>::new();
1313        bs.insert(0);
1314        bs.insert(1023);
1315        bs.insert(512);
1316        assert_eq!(bs.len(), 3);
1317
1318        let items: Vec<usize> = bs.iter().collect();
1319        assert_eq!(items, vec![0, 512, 1023]);
1320
1321        assert!(bs.remove(1023));
1322        assert!(!bs.contains(&1023));
1323
1324        // fill every word boundary
1325        let mut bs = BitSet::<[u64; 4], usize>::new();
1326        for i in (0..256).step_by(64) {
1327            bs.insert(i);
1328        }
1329        // also insert last bit of each word
1330        for i in (63..256).step_by(64) {
1331            bs.insert(i);
1332        }
1333        let items: Vec<usize> = bs.iter().collect();
1334        assert_eq!(items, vec![0, 63, 64, 127, 128, 191, 192, 255]);
1335    }
1336
1337    #[test]
1338    fn test_alias() {
1339        let mut bs = ArrayBitSet::<u64, usize, 2>::new();
1340        bs.set(5, true);
1341        bs.set(70, true);
1342        let items: Vec<usize> = bs.iter().collect();
1343        assert_eq!(items, vec![5, 70]);
1344    }
1345
1346    #[test]
1347    fn test_bitor() {
1348        let a = BitSet::<[u64; 2], usize>::from_element(10);
1349        let b = BitSet::<[u64; 2], usize>::from_element(100);
1350        let c = a | b;
1351        let items: Vec<usize> = c.iter().collect();
1352        assert_eq!(items, vec![10, 100]);
1353    }
1354
1355    #[test]
1356    fn test_array_set_relations() {
1357        let mut a = BitSet::<[u64; 2], usize>::new();
1358        a.set(1, true);
1359        a.set(65, true);
1360
1361        let mut b = BitSet::<[u64; 2], usize>::new();
1362        b.set(1, true);
1363        b.set(65, true);
1364        b.set(100, true);
1365
1366        let mut c = BitSet::<[u64; 2], usize>::new();
1367        c.set(2, true);
1368        c.set(66, true);
1369
1370        assert!(a.is_subset(&b));
1371        assert!(!b.is_subset(&a));
1372        assert!(b.is_superset(&a));
1373        assert!(!a.is_superset(&b));
1374        assert!(a.is_disjoint(&c));
1375        assert!(!a.is_disjoint(&b));
1376    }
1377
1378    #[test]
1379    fn test_prim_toggle() {
1380        let mut bs = BitSet::<u64, usize>::new();
1381        bs.insert(3);
1382        bs.toggle(3);
1383        assert!(!bs.contains(&3));
1384        bs.toggle(3);
1385        assert!(bs.contains(&3));
1386        bs.toggle(10);
1387        assert!(bs.contains(&10));
1388    }
1389
1390    #[test]
1391    fn test_array_toggle() {
1392        let mut bs = BitSet::<[u64; 2], usize>::new();
1393        bs.insert(5);
1394        bs.insert(70);
1395        bs.toggle(5);
1396        assert!(!bs.contains(&5));
1397        bs.toggle(70);
1398        assert!(!bs.contains(&70));
1399        bs.toggle(100);
1400        assert!(bs.contains(&100));
1401    }
1402
1403    #[test]
1404    fn test_prim_format_traits() {
1405        use alloc::format;
1406        let bs = BitSet::<u64, usize>::from_bits(0b1010);
1407        assert_eq!(format!("{bs:b}"), "1010");
1408        assert_eq!(format!("{bs:o}"), "12");
1409        assert_eq!(format!("{bs:x}"), "a");
1410        assert_eq!(format!("{bs:X}"), "A");
1411    }
1412
1413    #[test]
1414    fn test_prim_from_iter_self() {
1415        let sets = [
1416            BitSet::<u64, usize>::from_index(3),
1417            BitSet::<u64, usize>::from_index(7),
1418            BitSet::<u64, usize>::from_index(42),
1419        ];
1420        let merged: BitSet<u64, usize> = sets.into_iter().collect();
1421        assert!(merged.contains(&3));
1422        assert!(merged.contains(&7));
1423        assert!(merged.contains(&42));
1424        assert_eq!(merged.len(), 3);
1425    }
1426
1427    #[test]
1428    fn test_prim_extend_self() {
1429        let mut bs = BitSet::<u64, usize>::from_index(1);
1430        bs.extend([
1431            BitSet::<u64, usize>::from_index(5),
1432            BitSet::<u64, usize>::from_index(10),
1433        ]);
1434        assert!(bs.contains(&1));
1435        assert!(bs.contains(&5));
1436        assert!(bs.contains(&10));
1437    }
1438
1439    #[test]
1440    fn test_array_from_iter_self() {
1441        let sets = [
1442            BitSet::<[u64; 2], usize>::from_element(10),
1443            BitSet::<[u64; 2], usize>::from_element(100),
1444        ];
1445        let merged: BitSet<[u64; 2], usize> = sets.into_iter().collect();
1446        assert!(merged.contains(&10));
1447        assert!(merged.contains(&100));
1448        assert_eq!(merged.len(), 2);
1449    }
1450
1451    #[test]
1452    fn test_array_extend_self() {
1453        let mut bs = BitSet::<[u64; 2], usize>::from_element(5);
1454        bs.extend([BitSet::<[u64; 2], usize>::from_element(70)]);
1455        assert!(bs.contains(&5));
1456        assert!(bs.contains(&70));
1457    }
1458
1459    #[test]
1460    fn test_iter_size_hint_and_count_remaining() {
1461        let mut bs = BitSet::<[u64; 2], usize>::new();
1462        bs.insert(1);
1463        bs.insert(3);
1464        bs.insert(64);
1465        bs.insert(100);
1466
1467        let mut iter = bs.iter();
1468        assert_eq!(iter.size_hint(), (4, Some(4)));
1469        assert_eq!(iter.next(), Some(1));
1470        assert_eq!(iter.size_hint(), (3, Some(3)));
1471        assert_eq!(iter.next(), Some(3));
1472        assert_eq!(iter.size_hint(), (2, Some(2)));
1473        assert_eq!(iter.count(), 2);
1474    }
1475
1476    #[test]
1477    fn test_retain() {
1478        let mut bs = BitSet::<[u64; 2], usize>::new();
1479        for i in [1, 3, 5, 64, 66, 100] {
1480            bs.insert(i);
1481        }
1482        // keep only even positions
1483        bs.retain(|v| v % 2 == 0);
1484        let items: Vec<usize> = bs.iter().collect();
1485        assert_eq!(items, vec![64, 66, 100]);
1486    }
1487
1488    #[test]
1489    fn test_prim_retain() {
1490        let mut bs = BitSet::<u64, usize>::new();
1491        for i in [0, 1, 2, 3, 4, 5] {
1492            bs.insert(i);
1493        }
1494        bs.retain(|v| v >= 3);
1495        let items: Vec<usize> = bs.iter().collect();
1496        assert_eq!(items, vec![3, 4, 5]);
1497    }
1498
1499    #[test]
1500    fn test_append() {
1501        let mut a = BitSet::<[u64; 2], usize>::new();
1502        a.insert(1);
1503        a.insert(65);
1504
1505        let mut b = BitSet::<[u64; 2], usize>::new();
1506        b.insert(2);
1507        b.insert(65);
1508        b.insert(100);
1509
1510        a.append(&mut b);
1511        assert_eq!(a.len(), 4); // {1, 2, 65, 100}
1512        assert!(a.contains(&1));
1513        assert!(a.contains(&2));
1514        assert!(a.contains(&65));
1515        assert!(a.contains(&100));
1516        assert!(b.is_empty());
1517    }
1518
1519    #[test]
1520    fn test_difference() {
1521        let mut a = BitSet::<[u64; 2], usize>::new();
1522        a.insert(1);
1523        a.insert(5);
1524        a.insert(65);
1525
1526        let mut b = BitSet::<[u64; 2], usize>::new();
1527        b.insert(5);
1528        b.insert(10);
1529        b.insert(65);
1530
1531        let diff: Vec<usize> = a.difference(&b).collect();
1532        assert_eq!(diff, vec![1]);
1533    }
1534
1535    #[test]
1536    fn test_intersection() {
1537        let mut a = BitSet::<[u64; 2], usize>::new();
1538        a.insert(1);
1539        a.insert(5);
1540        a.insert(65);
1541
1542        let mut b = BitSet::<[u64; 2], usize>::new();
1543        b.insert(5);
1544        b.insert(10);
1545        b.insert(65);
1546
1547        let inter: Vec<usize> = a.intersection(&b).collect();
1548        assert_eq!(inter, vec![5, 65]);
1549    }
1550
1551    #[test]
1552    fn test_union_iter() {
1553        let mut a = BitSet::<[u64; 2], usize>::new();
1554        a.insert(1);
1555        a.insert(5);
1556
1557        let mut b = BitSet::<[u64; 2], usize>::new();
1558        b.insert(5);
1559        b.insert(70);
1560
1561        let uni: Vec<usize> = a.union(&b).collect();
1562        assert_eq!(uni, vec![1, 5, 70]);
1563    }
1564
1565    #[test]
1566    fn test_symmetric_difference() {
1567        let mut a = BitSet::<[u64; 2], usize>::new();
1568        a.insert(1);
1569        a.insert(5);
1570        a.insert(65);
1571
1572        let mut b = BitSet::<[u64; 2], usize>::new();
1573        b.insert(5);
1574        b.insert(10);
1575        b.insert(65);
1576
1577        let sym_diff: Vec<usize> = a.symmetric_difference(&b).collect();
1578        assert_eq!(sym_diff, vec![1, 10]);
1579    }
1580}