bittle/
set.rs

1use core::cmp;
2use core::fmt;
3use core::hash::{Hash, Hasher};
4use core::marker::PhantomData;
5use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
6
7use crate::bits::Bits;
8use crate::bits_mut::BitsMut;
9use crate::bits_owned::BitsOwned;
10use crate::endian::{DefaultEndian, Endian, LittleEndian};
11
12/// Convenience wrapper around bitsets providing the wrapped type with behaviors
13/// you'd expected out of a set-like container.
14///
15/// <br>
16///
17/// ## Persistent endianness
18///
19/// A set can be constructed with a custom endianness that it remembers, so that
20/// methods such as [`Bits::iter_ones`] uses the endianness in the type.
21///
22/// ```
23/// use bittle::{Bits, Set, LittleEndian};
24///
25/// let set: Set<u16> = bittle::set![1, 12];
26/// assert!(set.iter_ones().eq([1, 12]));
27/// assert_eq!(set.into_bits(), 0b00010000_00000010);
28///
29/// let set: Set<u16, LittleEndian> = bittle::set![1, 12];
30/// assert!(set.iter_ones().eq([1, 12]));
31/// assert_eq!(set.into_bits(), 0b01000000_00001000);
32/// ```
33///
34/// <br>
35///
36/// ## Debugging
37///
38/// A reason one might want to use this wrapper is to have a [Debug][fmt::Debug]
39/// implementation which shows which bits are actually in use:
40///
41/// ```
42/// use bittle::{Bits, Set, LittleEndian};
43///
44/// let set: u128 = bittle::set![1, 14];
45/// assert_eq!(format!("{set:?}"), "16386");
46///
47/// let set: Set<u128> = Set::new(set);
48/// assert_eq!(format!("{set:?}"), "{1, 14}");
49///
50/// let set: u128 = bittle::set_le![1, 14];
51/// assert_eq!(format!("{set:?}"), "85080976323951685521100712850600493056");
52///
53/// let set: Set<u128, LittleEndian> = Set::new_le(set);
54/// assert_eq!(format!("{set:?}"), "{1, 14}");
55/// ```
56///
57/// <br>
58///
59/// ## Standard iteration
60///
61/// This wrapper provides unambigious implementations of [`IntoIterator`] which
62/// delegates to [`Bits::iter_ones`], avoiding potential confusion when using an
63/// array as a set:
64///
65/// ```
66/// use bittle::Set;
67///
68/// let array = [0b00001000u8, 0b0u8];
69/// assert!(array.into_iter().eq([8, 0]));
70///
71/// let set = Set::new(array);
72/// assert!(set.into_iter().eq([3]));
73/// ```
74///
75/// <br>
76///
77/// ## Standard operators
78///
79/// Wrapping into a [Set] also provides us with [`BitOr`], [`BitAnd`],
80/// [`BitXor`], [`Sub`], and [`BitOrAssign`], [`BitAndAssign`],
81/// [`BitXorAssign`], [`SubAssign`] implementations to work with. They each
82/// refer to [`BitsOwned::union`], [`BitsOwned::conjunction`],
83/// [`BitsOwned::symmetric_difference`], and [`BitsOwned::difference`]
84/// respectively.
85///
86/// ```
87/// use bittle::{Bits, Set};
88///
89/// let set1: Set<[u32; 4]> = bittle::set![1, 65];
90/// let set2: Set<[u32; 4]> = bittle::set![65, 110];
91///
92/// assert!((set1 | set2).iter_ones().eq([1, 65, 110]));
93/// assert!((set1 & set2).iter_ones().eq([65]));
94/// assert!((set1 ^ set2).iter_ones().eq([1, 110]));
95/// assert!((set1 - set2).iter_ones().eq([1]));
96///
97/// let mut set3 = set1.clone();
98/// set3 |= &set2;
99/// assert!(set3.iter_ones().eq([1, 65, 110]));
100///
101/// let mut set3 = set1.clone();
102/// set3 &= &set2;
103/// assert!(set3.iter_ones().eq([65]));
104///
105/// let mut set3 = set1.clone();
106/// set3 ^= &set2;
107/// assert!(set3.iter_ones().eq([1, 110]));
108///
109/// let mut set3 = set1.clone();
110/// set3 -= &set2;
111/// assert!(set3.iter_ones().eq([1]));
112/// ```
113///
114/// <br>
115///
116/// ## Equality and comparison
117///
118/// It also ensures that for operations that can be, are generic over bitwise
119/// indexes, allowing different kinds of bitsets to be compared:
120///
121/// ```
122/// use bittle::Set;
123/// let a = 0b00000000_00000000_00000001_00010000u32;
124/// let b = 0b00000001_00010000u16;
125/// let c = vec![0b00010000u8, 0b00000001u8];
126///
127/// assert_eq!(Set::new(a), Set::new(b));
128/// assert_eq!(Set::new(a), Set::from_ref(&c[..]));
129///
130/// let d = 0b00000001_11111111u16;
131/// assert!(Set::new(d) < Set::new(a));
132/// assert!(Set::new(d) < Set::new(b));
133/// assert!(Set::new(d) < Set::from_ref(&c[..]));
134/// ```
135///
136/// Note that if this result seems peculiar to you, consider that a bitset is
137/// actually an *ordered set*, so it would mimic the behavior of
138/// [`BTreeSet<u32>`] where `u32` are the indexes in
139/// the set rather than a direct numerical comparison:
140///
141/// ```
142/// use std::collections::BTreeSet;
143/// let mut a = BTreeSet::new();
144/// let mut b = BTreeSet::new();
145///
146/// a.insert(0u32);
147/// a.insert(1u32);
148/// b.insert(1u32);
149///
150/// assert!(a < b);
151/// ```
152///
153/// [`BTreeSet<u32>`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
154///
155/// # More Examples
156///
157/// ```
158/// use bittle::{Bits, BitsMut, BitsOwned, Set};
159///
160/// let mut a = Set::<u128>::zeros();
161///
162/// assert!(!a.test_bit(1));
163/// a.set_bit(1);
164/// assert!(a.test_bit(1));
165/// a.clear_bit(1);
166/// assert!(!a.test_bit(1));
167/// ```
168///
169/// The bit set can also use arrays as its backing storage.
170///
171/// ```
172/// use bittle::{Bits, BitsMut, BitsOwned, Set};
173///
174/// let mut a = Set::<[u64; 16]>::zeros();
175///
176/// assert!(!a.test_bit(172));
177/// a.set_bit(172);
178/// assert!(a.test_bit(172));
179/// a.clear_bit(172);
180/// assert!(!a.test_bit(172));
181/// ```
182///
183/// We can use the iterator of each set to compare bit sets of different kinds:
184///
185/// ```
186/// use bittle::{Bits, BitsMut, BitsOwned, Set};
187///
188/// let mut a = Set::<[u64; 2]>::zeros();
189/// let mut b = Set::<u128>::zeros();
190///
191/// a.set_bit(111);
192/// assert!(!a.iter_ones().eq(b.iter_ones()));
193///
194/// b.set_bit(111);
195/// assert!(a.iter_ones().eq(b.iter_ones()));
196/// ```
197#[repr(transparent)]
198pub struct Set<T, E = DefaultEndian>
199where
200    T: ?Sized,
201{
202    _shift: PhantomData<E>,
203    bits: T,
204}
205
206impl<T> Set<T> {
207    /// Construct a set from its underlying bits using [`DefaultEndian`].
208    ///
209    /// [`DefaultEndian`]: crate::DefaultEndian
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use bittle::{Bits, Set};
215    ///
216    /// let mut set = Set::new(0b00001001u32);
217    /// assert!(set.iter_ones().eq([0, 3]));
218    /// ```
219    #[inline]
220    pub const fn new(bits: T) -> Self {
221        Self::new_in(bits)
222    }
223}
224
225impl<T> Set<T, LittleEndian> {
226    /// Construct a set from its underlying bits using [`LittleEndian`] indexing.
227    ///
228    /// # Examples
229    ///
230    /// ```
231    /// use bittle::{Bits, Set};
232    ///
233    /// let mut set = Set::new_le(0b00001001u8);
234    /// assert!(set.iter_ones().eq([4, 7]));
235    /// ```
236    #[inline]
237    pub const fn new_le(bits: T) -> Self {
238        Self::new_in(bits)
239    }
240}
241
242impl<T, E> Set<T, E> {
243    /// Construct a set from its underlying bits using custom endianness.
244    ///
245    /// # Examples
246    ///
247    /// ```
248    /// use bittle::{Bits, Set, LittleEndian};
249    ///
250    /// let mut set: Set<u8, LittleEndian> = Set::new_in(0b00001001u8);
251    /// assert!(set.iter_ones().eq([4, 7]));
252    /// assert!(set.iter_ones_in::<LittleEndian>().eq([4, 7]));
253    /// ```
254    #[inline]
255    pub const fn new_in(bits: T) -> Self {
256        Self {
257            _shift: PhantomData,
258            bits,
259        }
260    }
261
262    /// Coerce into raw interior bits.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use bittle::{Bits, Set};
268    ///
269    /// let mut set = Set::new(0b00001001u8);
270    /// assert_eq!(set.into_bits(), 0b00001001u8);
271    ///
272    /// let mut set = Set::new_le(0b00001001u8);
273    /// assert_eq!(set.into_bits(), 0b00001001u8);
274    /// ```
275    #[inline]
276    pub fn into_bits(self) -> T {
277        self.bits
278    }
279}
280
281impl<T> Set<T>
282where
283    T: ?Sized,
284{
285    /// Wrap a reference as a set using [`DefaultEndian`] indexing.
286    ///
287    /// # Examples
288    ///
289    /// ```
290    /// use bittle::{Bits, Set};
291    ///
292    /// let mut set = Set::from_ref(&[0b00000001u8, 0b00010000u8]);
293    /// assert!(set.iter_ones().eq([0, 12]));
294    /// ```
295    #[inline]
296    pub fn from_ref<U>(bits: &U) -> &Self
297    where
298        U: ?Sized + AsRef<T>,
299    {
300        // SAFETY: Reference provided as bits has the same memory layout as
301        // &Set<T>.
302        unsafe { &*(bits.as_ref() as *const _ as *const _) }
303    }
304
305    /// Wrap a mutable reference as a set using [`DefaultEndian`] indexing.
306    ///
307    /// # Examples
308    ///
309    /// ```
310    /// use bittle::{Bits, BitsMut, Set};
311    ///
312    /// let mut values = [0b00000001u8, 0b00010000u8];
313    ///
314    /// let mut set = Set::from_mut(&mut values);
315    /// assert!(set.iter_ones().eq([0, 12]));
316    ///
317    /// set.set_bit(4);
318    /// assert_eq!(&values[..], &[0b00010001u8, 0b00010000u8]);
319    /// ```
320    #[inline]
321    pub fn from_mut<U>(bits: &mut U) -> &mut Self
322    where
323        U: ?Sized + AsMut<T>,
324    {
325        // SAFETY: Reference provided as bits has the same memory layout as &mut
326        // Set<T>.
327        unsafe { &mut *(bits.as_mut() as *mut _ as *mut _) }
328    }
329}
330
331impl<T> Set<T, LittleEndian>
332where
333    T: ?Sized,
334{
335    /// Wrap a reference as a set using [`LittleEndian`] indexing.
336    ///
337    /// # Examples
338    ///
339    /// ```
340    /// use bittle::{Bits, Set};
341    ///
342    /// let mut set = Set::from_ref_le(&[0b00000001u8, 0b00010000u8]);
343    /// assert!(set.iter_ones_le().eq([7, 11]));
344    /// ```
345    #[inline]
346    pub fn from_ref_le<U>(bits: &U) -> &Self
347    where
348        U: ?Sized + AsRef<T>,
349    {
350        // SAFETY: Reference provided as bits has the same memory layout as
351        // &Set<T>.
352        unsafe { &*(bits.as_ref() as *const _ as *const _) }
353    }
354
355    /// Wrap a mutable reference as a set using [`LittleEndian`] indexing.
356    ///
357    /// # Examples
358    ///
359    /// ```
360    /// use bittle::{Bits, BitsMut, Set, LittleEndian};
361    ///
362    /// let mut values = [0b00000001u8, 0b00010000u8];
363    ///
364    /// let mut set = Set::from_mut_le(&mut values);
365    /// assert!(set.iter_ones_le().eq([7, 11]));
366    ///
367    /// set.set_bit(4);
368    /// assert_eq!(&values[..], &[0b00001001u8, 0b00010000u8]);
369    /// ```
370    #[inline]
371    pub fn from_mut_le<U>(bits: &mut U) -> &mut Self
372    where
373        U: ?Sized + AsMut<T>,
374    {
375        // SAFETY: Reference provided as bits has the same memory layout as &mut
376        // Set<T>.
377        unsafe { &mut *(bits.as_mut() as *mut _ as *mut _) }
378    }
379}
380
381impl<T, E> Default for Set<T, E>
382where
383    T: BitsOwned,
384    E: Endian,
385{
386    /// Construct a new empty set.
387    ///
388    /// # Examples
389    ///
390    /// ```
391    /// use bittle::{Bits, BitsMut, BitsOwned, Set};
392    ///
393    /// let mut a = Set::<u32>::zeros();
394    ///
395    /// assert!(a.all_zeros());
396    /// a.set_bit(0);
397    /// assert!(!a.all_zeros());
398    /// ```
399    #[inline]
400    fn default() -> Self {
401        Self::new_in(T::ZEROS)
402    }
403}
404
405impl<T, U> Bits for Set<T, U>
406where
407    T: ?Sized + Bits,
408    U: Endian,
409{
410    type IterOnes<'a> = T::IterOnesIn<'a, U>
411    where
412        Self: 'a;
413
414    type IterOnesIn<'a, E> = T::IterOnesIn<'a, E>
415    where
416        Self: 'a,
417        E: Endian;
418
419    type IterZeros<'a> = T::IterZerosIn<'a, U>
420    where
421        Self: 'a;
422
423    type IterZerosIn<'a, E> = T::IterZerosIn<'a, E>
424    where
425        Self: 'a,
426        E: Endian;
427
428    #[inline]
429    fn count_ones(&self) -> u32 {
430        self.bits.count_ones()
431    }
432
433    #[inline]
434    fn count_zeros(&self) -> u32 {
435        self.bits.count_zeros()
436    }
437
438    #[inline]
439    fn bits_capacity(&self) -> u32 {
440        self.bits.bits_capacity()
441    }
442
443    #[inline]
444    fn all_ones(&self) -> bool {
445        self.bits.all_ones()
446    }
447
448    #[inline]
449    fn all_zeros(&self) -> bool {
450        self.bits.all_zeros()
451    }
452
453    #[inline]
454    fn test_bit(&self, index: u32) -> bool {
455        self.bits.test_bit_in::<U>(index)
456    }
457
458    #[inline]
459    fn test_bit_in<E>(&self, index: u32) -> bool
460    where
461        E: Endian,
462    {
463        self.bits.test_bit_in::<E>(index)
464    }
465
466    #[inline]
467    fn iter_ones(&self) -> Self::IterOnes<'_> {
468        self.bits.iter_ones_in()
469    }
470
471    #[inline]
472    fn iter_ones_in<E>(&self) -> Self::IterOnesIn<'_, E>
473    where
474        E: Endian,
475    {
476        self.bits.iter_ones_in()
477    }
478
479    #[inline]
480    fn iter_zeros(&self) -> Self::IterZeros<'_> {
481        self.bits.iter_zeros_in()
482    }
483
484    #[inline]
485    fn iter_zeros_in<E>(&self) -> Self::IterZerosIn<'_, E>
486    where
487        E: Endian,
488    {
489        self.bits.iter_zeros_in()
490    }
491}
492
493impl<T, U> BitsMut for Set<T, U>
494where
495    T: ?Sized + BitsMut,
496    U: Endian,
497{
498    #[inline]
499    fn set_bit_in<E>(&mut self, index: u32)
500    where
501        E: Endian,
502    {
503        self.bits.set_bit_in::<E>(index);
504    }
505
506    #[inline]
507    fn set_bit(&mut self, index: u32) {
508        self.bits.set_bit_in::<U>(index);
509    }
510
511    #[inline]
512    fn clear_bit_in<E>(&mut self, index: u32)
513    where
514        E: Endian,
515    {
516        self.bits.clear_bit_in::<E>(index);
517    }
518
519    #[inline]
520    fn clear_bit(&mut self, index: u32) {
521        self.bits.clear_bit_in::<U>(index);
522    }
523
524    #[inline]
525    fn clear_bits(&mut self) {
526        self.bits.clear_bits();
527    }
528
529    #[inline]
530    fn union_assign(&mut self, other: &Self) {
531        self.bits.union_assign(&other.bits);
532    }
533
534    #[inline]
535    fn conjunction_assign(&mut self, other: &Self) {
536        self.bits.conjunction_assign(&other.bits);
537    }
538
539    #[inline]
540    fn difference_assign(&mut self, other: &Self) {
541        self.bits.difference_assign(&other.bits);
542    }
543
544    #[inline]
545    fn symmetric_difference_assign(&mut self, other: &Self) {
546        self.bits.symmetric_difference_assign(&other.bits);
547    }
548}
549
550impl<T, U> BitsOwned for Set<T, U>
551where
552    T: BitsOwned,
553    U: Endian,
554{
555    const BITS: u32 = T::BITS;
556    const ONES: Self = Self::new_in(T::ONES);
557    const ZEROS: Self = Self::new_in(T::ZEROS);
558
559    type IntoIterOnes = T::IntoIterOnesIn<U>;
560    type IntoIterOnesIn<E> = T::IntoIterOnesIn<E> where E: Endian;
561    type IntoIterZeros = T::IntoIterZerosIn<U>;
562    type IntoIterZerosIn<E> = T::IntoIterZerosIn<E> where E: Endian;
563
564    #[inline]
565    fn zeros() -> Self {
566        Self::new_in(T::ZEROS)
567    }
568
569    #[inline]
570    fn ones() -> Self {
571        Self::new_in(T::ONES)
572    }
573
574    #[inline]
575    fn with_bit_in<E>(self, bit: u32) -> Self
576    where
577        E: Endian,
578    {
579        Self::new_in(self.bits.with_bit_in::<E>(bit))
580    }
581
582    #[inline]
583    fn with_bit(self, bit: u32) -> Self {
584        Self::new_in(self.bits.with_bit_in::<U>(bit))
585    }
586
587    #[inline]
588    fn without_bit_in<E>(self, bit: u32) -> Self
589    where
590        E: Endian,
591    {
592        Self::new_in(self.bits.without_bit_in::<E>(bit))
593    }
594
595    #[inline]
596    fn without_bit(self, bit: u32) -> Self {
597        Self::new_in(self.bits.without_bit_in::<U>(bit))
598    }
599
600    #[inline]
601    fn union(self, other: Self) -> Self {
602        Self::new_in(self.bits.union(other.bits))
603    }
604
605    #[inline]
606    fn conjunction(self, other: Self) -> Self {
607        Self::new_in(self.bits.conjunction(other.bits))
608    }
609
610    #[inline]
611    fn difference(self, other: Self) -> Self {
612        Self::new_in(self.bits.difference(other.bits))
613    }
614
615    #[inline]
616    fn symmetric_difference(self, other: Self) -> Self {
617        Self::new_in(self.bits.symmetric_difference(other.bits))
618    }
619
620    #[inline]
621    fn into_iter_ones(self) -> Self::IntoIterOnes {
622        self.bits.into_iter_ones_in()
623    }
624
625    #[inline]
626    fn into_iter_ones_in<E>(self) -> Self::IntoIterOnesIn<E>
627    where
628        E: Endian,
629    {
630        self.bits.into_iter_ones_in()
631    }
632
633    #[inline]
634    fn into_iter_zeros(self) -> Self::IntoIterZeros {
635        self.bits.into_iter_zeros_in()
636    }
637
638    #[inline]
639    fn into_iter_zeros_in<E>(self) -> Self::IntoIterZerosIn<E>
640    where
641        E: Endian,
642    {
643        self.bits.into_iter_zeros_in()
644    }
645}
646
647impl<T, E> Clone for Set<T, E>
648where
649    T: Clone,
650{
651    #[inline]
652    fn clone(&self) -> Self {
653        Self::new_in(self.bits.clone())
654    }
655}
656
657impl<T, E> Copy for Set<T, E> where T: Copy {}
658
659impl<T, E> fmt::Debug for Set<T, E>
660where
661    T: ?Sized + Bits,
662    E: Endian,
663{
664    #[inline]
665    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
666        f.debug_set().entries(self.iter_ones_in::<E>()).finish()
667    }
668}
669
670/// Flexible [`PartialEq`] implementation which allows for comparisons between different kinds of sets.
671///
672/// # Examples
673///
674/// ```
675/// use bittle::Set;
676///
677/// let a = Set::new(0b00001000u8);
678/// let b = Set::new(0b00000000_00001000u16);
679/// let c = Set::new([0b00001000u8, 0]);
680///
681/// assert_eq!(a, b);
682/// assert_eq!(a, c);
683/// ```
684impl<T, U, E> cmp::PartialEq<U> for Set<T, E>
685where
686    T: ?Sized + Bits,
687    U: ?Sized + Bits,
688    E: Endian,
689{
690    #[inline]
691    fn eq(&self, other: &U) -> bool {
692        self.iter_ones_in::<E>().eq(other.iter_ones_in::<E>())
693    }
694}
695
696impl<T, E> cmp::Eq for Set<T, E>
697where
698    T: ?Sized + Bits,
699    E: Endian,
700{
701}
702
703impl<T, U, E> cmp::PartialOrd<U> for Set<T, E>
704where
705    T: ?Sized + Bits,
706    U: ?Sized + Bits,
707    E: Endian,
708{
709    #[inline]
710    fn partial_cmp(&self, other: &U) -> Option<cmp::Ordering> {
711        self.iter_ones_in::<E>()
712            .partial_cmp(other.iter_ones_in::<E>())
713    }
714}
715
716impl<T, E> cmp::Ord for Set<T, E>
717where
718    T: ?Sized + Bits,
719    E: Endian,
720{
721    #[inline]
722    fn cmp(&self, other: &Self) -> cmp::Ordering {
723        self.iter_ones_in::<E>().cmp(other.iter_ones_in::<E>())
724    }
725}
726
727impl<T, E> Hash for Set<T, E>
728where
729    T: ?Sized + Hash,
730{
731    #[inline]
732    fn hash<H: Hasher>(&self, state: &mut H) {
733        self.bits.hash(state);
734    }
735}
736
737impl<T, E> IntoIterator for Set<T, E>
738where
739    T: BitsOwned,
740    E: Endian,
741{
742    type IntoIter = T::IntoIterOnesIn<E>;
743    type Item = <Self::IntoIter as Iterator>::Item;
744
745    #[inline]
746    fn into_iter(self) -> Self::IntoIter {
747        self.bits.into_iter_ones_in()
748    }
749}
750
751impl<'a, T, E> IntoIterator for &'a Set<T, E>
752where
753    T: ?Sized + Bits,
754    E: Endian,
755{
756    type IntoIter = T::IterOnesIn<'a, E>;
757    type Item = <Self::IntoIter as Iterator>::Item;
758
759    #[inline]
760    fn into_iter(self) -> Self::IntoIter {
761        self.iter_ones_in::<E>()
762    }
763}
764
765impl<T, E> From<T> for Set<T, E>
766where
767    T: BitsOwned,
768    E: Endian,
769{
770    #[inline]
771    fn from(bits: T) -> Self {
772        Self::new_in(bits)
773    }
774}
775
776macro_rules! owned_ops {
777    ($trait:ident::$n:ident, $name:ident<$t:ident, $s:ident>, $fn:ident) => {
778        impl<$t, $s> $trait<$name<$t, $s>> for $name<$t, $s>
779        where
780            $t: BitsOwned,
781            $s: Endian,
782        {
783            type Output = $name<$t, $s>;
784
785            #[inline]
786            fn $n(self, rhs: $name<$t, $s>) -> Self::Output {
787                $name::new_in(self.bits.$fn(rhs.bits))
788            }
789        }
790
791        impl<$t, $s> $trait<&$name<$t, $s>> for $name<$t, $s>
792        where
793            $t: Copy + BitsOwned,
794            $s: Endian,
795        {
796            type Output = $name<$t, $s>;
797
798            #[inline]
799            fn $n(self, rhs: &$name<$t, $s>) -> Self::Output {
800                $name::new_in(self.bits.$fn(rhs.bits))
801            }
802        }
803
804        impl<$t, $s> $trait<$name<$t, $s>> for &$name<$t, $s>
805        where
806            $t: Copy + BitsOwned,
807            $s: Endian,
808        {
809            type Output = $name<$t, $s>;
810
811            #[inline]
812            fn $n(self, rhs: $name<$t, $s>) -> Self::Output {
813                $name::new_in(self.bits.$fn(rhs.bits))
814            }
815        }
816
817        impl<$t, $s> $trait<&$name<$t, $s>> for &$name<$t, $s>
818        where
819            $t: Copy + BitsOwned,
820            $s: Endian,
821        {
822            type Output = $name<$t, $s>;
823
824            #[inline]
825            fn $n(self, rhs: &$name<$t, $s>) -> Self::Output {
826                $name::new_in(self.bits.$fn(rhs.bits))
827            }
828        }
829    };
830}
831
832macro_rules! assign_ops {
833    ($trait:ident::$n:ident, $name:ident<$t:ident, $s:ident>, $fn:ident) => {
834        impl<$t, $s> $trait<$name<$t, $s>> for $name<$t, $s>
835        where
836            $t: BitsMut,
837        {
838            #[inline]
839            fn $n(&mut self, rhs: $name<$t, $s>) {
840                self.bits.$fn(&rhs.bits);
841            }
842        }
843
844        impl<$t, $s> $trait<&$name<$t, $s>> for $name<$t, $s>
845        where
846            $t: BitsMut,
847        {
848            #[inline]
849            fn $n(&mut self, rhs: &$name<$t, $s>) {
850                self.bits.$fn(&rhs.bits);
851            }
852        }
853
854        impl<$t, $s> $trait<&$name<$t, $s>> for &mut $name<$t, $s>
855        where
856            $t: BitsMut,
857        {
858            #[inline]
859            fn $n(&mut self, rhs: &$name<$t, $s>) {
860                self.bits.$fn(&rhs.bits);
861            }
862        }
863    };
864}
865
866owned_ops!(BitOr::bitor, Set<T, E>, union);
867assign_ops!(BitOrAssign::bitor_assign, Set<T, E>, union_assign);
868owned_ops!(BitAnd::bitand, Set<T, E>, conjunction);
869assign_ops!(BitAndAssign::bitand_assign, Set<T, E>, conjunction_assign);
870owned_ops!(BitXor::bitxor, Set<T, E>, symmetric_difference);
871assign_ops!(
872    BitXorAssign::bitxor_assign,
873    Set<T, E>,
874    symmetric_difference_assign
875);
876owned_ops!(Sub::sub, Set<T, E>, difference);
877assign_ops!(SubAssign::sub_assign, Set<T, E>, difference_assign);