1use crate::repr::EnumSetTypeRepr;
2use crate::traits::{EnumSetConstHelper, EnumSetType};
3use crate::EnumSetTypeWithRepr;
4use core::cmp::Ordering;
5use core::fmt::{Debug, Display, Formatter};
6use core::hash::{Hash, Hasher};
7use core::iter::Sum;
8use core::ops::{
9 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign,
10};
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(Copy, Clone, PartialEq, Eq)]
96#[repr(transparent)]
97pub struct EnumSet<T: EnumSetType> {
98 pub(crate) repr: T::Repr,
99}
100
101impl<T: EnumSetType> EnumSet<T> {
103 const EMPTY_REPR: Self = EnumSet { repr: T::Repr::EMPTY };
104 const ALL_REPR: Self = EnumSet { repr: T::ALL_BITS };
105
106 #[inline(always)]
108 pub const fn new() -> Self {
109 Self::EMPTY_REPR
110 }
111
112 #[inline(always)]
114 pub fn only(t: T) -> Self {
115 let mut set = Self::new();
116 set.insert(t);
117 set
118 }
119
120 #[inline(always)]
124 pub const fn empty() -> Self {
125 Self::EMPTY_REPR
126 }
127
128 #[inline(always)]
130 pub const fn all() -> Self {
131 Self::ALL_REPR
132 }
133
134 #[inline(always)]
140 pub const fn bit_width() -> u32 {
141 T::BIT_WIDTH
142 }
143
144 #[inline(always)]
149 pub const fn variant_count() -> u32 {
150 T::VARIANT_COUNT
151 }
152
153 #[inline(always)]
155 pub fn len(&self) -> usize {
156 self.repr.count_ones() as usize
157 }
158 #[inline(always)]
160 pub fn is_empty(&self) -> bool {
161 self.repr.is_empty()
162 }
163 #[inline(always)]
165 pub fn clear(&mut self) {
166 self.repr = T::Repr::EMPTY;
167 }
168
169 #[inline(always)]
172 pub fn is_disjoint(&self, other: Self) -> bool {
173 (*self & other).is_empty()
174 }
175 #[inline(always)]
178 pub fn is_superset(&self, other: Self) -> bool {
179 (*self & other).repr == other.repr
180 }
181 #[inline(always)]
184 pub fn is_subset(&self, other: Self) -> bool {
185 other.is_superset(*self)
186 }
187
188 #[inline(always)]
190 pub fn union(&self, other: Self) -> Self {
191 EnumSet { repr: self.repr | other.repr }
192 }
193 #[inline(always)]
195 pub fn intersection(&self, other: Self) -> Self {
196 EnumSet { repr: self.repr & other.repr }
197 }
198 #[inline(always)]
200 pub fn difference(&self, other: Self) -> Self {
201 EnumSet { repr: self.repr.and_not(other.repr) }
202 }
203 #[inline(always)]
206 pub fn symmetrical_difference(&self, other: Self) -> Self {
207 EnumSet { repr: self.repr ^ other.repr }
208 }
209 #[inline(always)]
211 pub fn complement(&self) -> Self {
212 EnumSet { repr: !self.repr & T::ALL_BITS }
213 }
214
215 #[inline(always)]
217 pub fn contains(&self, value: T) -> bool {
218 self.repr.has_bit(value.enum_into_u32())
219 }
220
221 #[inline(always)]
227 pub fn insert(&mut self, value: T) -> bool {
228 let contains = !self.contains(value);
229 self.repr.add_bit(value.enum_into_u32());
230 contains
231 }
232 #[inline(always)]
234 pub fn remove(&mut self, value: T) -> bool {
235 let contains = self.contains(value);
236 self.repr.remove_bit(value.enum_into_u32());
237 contains
238 }
239
240 #[inline(always)]
242 pub fn insert_all(&mut self, other: Self) {
243 self.repr = self.repr | other.repr
244 }
245 #[inline(always)]
247 pub fn remove_all(&mut self, other: Self) {
248 self.repr = self.repr.and_not(other.repr);
249 }
250}
251
252#[doc(hidden)]
254pub struct EnumSetInitHelper;
255impl EnumSetInitHelper {
256 pub const fn const_only<T>(&self, value: T) -> T {
259 value
260 }
261}
262
263#[doc(hidden)]
264unsafe impl<T: EnumSetType> EnumSetConstHelper for EnumSet<T> {
265 type ConstInitHelper = EnumSetInitHelper;
266 const CONST_INIT_HELPER: Self::ConstInitHelper = EnumSetInitHelper;
267
268 type ConstOpHelper = T::ConstOpHelper;
269 const CONST_OP_HELPER: Self::ConstOpHelper = T::CONST_OP_HELPER;
270}
271
272impl<T: EnumSetType> Default for EnumSet<T> {
273 fn default() -> Self {
275 Self::new()
276 }
277}
278
279impl<T: EnumSetType, O: Into<EnumSet<T>>> Sub<O> for EnumSet<T> {
280 type Output = Self;
281 #[inline(always)]
282 fn sub(self, other: O) -> Self::Output {
283 self.difference(other.into())
284 }
285}
286impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAnd<O> for EnumSet<T> {
287 type Output = Self;
288 #[inline(always)]
289 fn bitand(self, other: O) -> Self::Output {
290 self.intersection(other.into())
291 }
292}
293impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOr<O> for EnumSet<T> {
294 type Output = Self;
295 #[inline(always)]
296 fn bitor(self, other: O) -> Self::Output {
297 self.union(other.into())
298 }
299}
300impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXor<O> for EnumSet<T> {
301 type Output = Self;
302 #[inline(always)]
303 fn bitxor(self, other: O) -> Self::Output {
304 self.symmetrical_difference(other.into())
305 }
306}
307
308impl<T: EnumSetType, O: Into<EnumSet<T>>> SubAssign<O> for EnumSet<T> {
309 #[inline(always)]
310 fn sub_assign(&mut self, rhs: O) {
311 *self = *self - rhs;
312 }
313}
314impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAndAssign<O> for EnumSet<T> {
315 #[inline(always)]
316 fn bitand_assign(&mut self, rhs: O) {
317 *self = *self & rhs;
318 }
319}
320impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOrAssign<O> for EnumSet<T> {
321 #[inline(always)]
322 fn bitor_assign(&mut self, rhs: O) {
323 *self = *self | rhs;
324 }
325}
326impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXorAssign<O> for EnumSet<T> {
327 #[inline(always)]
328 fn bitxor_assign(&mut self, rhs: O) {
329 *self = *self ^ rhs;
330 }
331}
332
333impl<T: EnumSetType> Not for EnumSet<T> {
334 type Output = Self;
335 #[inline(always)]
336 fn not(self) -> Self::Output {
337 self.complement()
338 }
339}
340
341impl<T: EnumSetType> From<T> for EnumSet<T> {
342 fn from(t: T) -> Self {
343 EnumSet::only(t)
344 }
345}
346
347impl<T: EnumSetType> PartialEq<T> for EnumSet<T> {
348 fn eq(&self, other: &T) -> bool {
349 self.repr == EnumSet::only(*other).repr
350 }
351}
352
353impl<T: EnumSetType + Debug> Debug for EnumSet<T> {
354 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
355 f.write_str("EnumSet(")?;
357 let mut i = self.iter();
358 if let Some(v) = i.next() {
359 v.fmt(f)?;
360 for v in i {
361 f.write_str(" | ")?;
362 v.fmt(f)?;
363 }
364 }
365 f.write_str(")")?;
366 Ok(())
367 }
368}
369impl<T: EnumSetType + Display> Display for EnumSet<T> {
370 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
371 let mut i = self.iter();
372 if let Some(v) = i.next() {
373 v.fmt(f)?;
374 for v in i {
375 f.write_str(" | ")?;
376 v.fmt(f)?;
377 }
378 }
379 Ok(())
380 }
381}
382
383#[cfg(feature = "defmt")]
384impl<T: EnumSetType + defmt::Format> defmt::Format for EnumSet<T> {
385 fn format(&self, f: defmt::Formatter) {
386 let mut i = self.iter();
387 if let Some(v) = i.next() {
388 defmt::write!(f, "{}", v);
389 for v in i {
390 defmt::write!(f, " | {}", v);
391 }
392 }
393 }
394}
395
396#[allow(clippy::derived_hash_with_manual_eq)] impl<T: EnumSetType> Hash for EnumSet<T> {
398 fn hash<H: Hasher>(&self, state: &mut H) {
399 self.repr.hash(state)
400 }
401}
402#[allow(clippy::non_canonical_partial_ord_impl)]
403impl<T: EnumSetType> PartialOrd for EnumSet<T> {
404 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
405 self.repr.partial_cmp(&other.repr)
406 }
407}
408impl<T: EnumSetType> Ord for EnumSet<T> {
409 fn cmp(&self, other: &Self) -> Ordering {
410 self.repr.cmp(&other.repr)
411 }
412}
413
414#[cfg(feature = "serde")]
415impl<T: EnumSetType> Serialize for EnumSet<T> {
416 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
417 T::serialize(*self, serializer)
418 }
419}
420
421#[cfg(feature = "serde")]
422impl<'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
423 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
424 T::deserialize(deserializer)
425 }
426}
427impl<T: EnumSetType> EnumSet<T> {
432 #[deprecated = "Use `EnumSet::empty()` instead."]
436 pub const EMPTY: Self = Self::EMPTY_REPR;
437
438 #[deprecated = "Use `EnumSet::all()` instead."]
442 pub const ALL: Self = Self::ALL_REPR;
443}
444impl<T: EnumSetType + EnumSetTypeWithRepr> EnumSet<T> {
448 #[inline(always)]
457 pub const fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr {
458 self.repr
459 }
460
461 #[inline(always)]
475 pub unsafe fn from_repr_unchecked(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
476 Self { repr: bits }
477 }
478
479 #[inline(always)]
488 pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
489 Self::try_from_repr(bits).expect("Bitset contains invalid variants.")
490 }
491
492 #[inline(always)]
501 pub fn try_from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Option<Self> {
502 let mask = Self::all().repr;
503 if bits.and_not(mask).is_empty() {
504 Some(EnumSet { repr: bits })
505 } else {
506 None
507 }
508 }
509
510 #[inline(always)]
516 pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
517 let mask = Self::all().as_repr();
518 let bits = bits & mask;
519 EnumSet { repr: bits }
520 }
521}
522
523macro_rules! conversion_impls {
525 (
526 $(for_num!(
527 $underlying:ty, $underlying_str:expr,
528 $from_fn:ident $to_fn:ident $from_fn_opt:ident $to_fn_opt:ident,
529 $from:ident $try_from:ident $from_truncated:ident $from_unchecked:ident,
530 $to:ident $try_to:ident $to_truncated:ident
531 );)*
532 ) => {
533 impl<T: EnumSetType> EnumSet<T> {$(
534 #[doc = "Returns a `"]
535 #[doc = $underlying_str]
536 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
537 not fit in a `"]
538 #[doc = $underlying_str]
539 #[doc = "`, this method will panic."]
540 #[inline(always)]
541 pub fn $to(&self) -> $underlying {
542 self.$try_to().expect("Bitset will not fit into this type.")
543 }
544
545 #[doc = "Tries to return a `"]
546 #[doc = $underlying_str]
547 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
548 not fit in a `"]
549 #[doc = $underlying_str]
550 #[doc = "`, this method will panic."]
551 #[inline(always)]
552 pub fn $try_to(&self) -> Option<$underlying> {
553 EnumSetTypeRepr::$to_fn_opt(&self.repr)
554 }
555
556 #[doc = "Returns a truncated `"]
557 #[doc = $underlying_str]
558 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
559 not fit in a `"]
560 #[doc = $underlying_str]
561 #[doc = "`, this method will truncate any bits that don't fit."]
562 #[inline(always)]
563 pub fn $to_truncated(&self) -> $underlying {
564 EnumSetTypeRepr::$to_fn(&self.repr)
565 }
566
567 #[doc = "Constructs a bitset from a `"]
568 #[doc = $underlying_str]
569 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
570 method will panic."]
571 #[inline(always)]
572 pub fn $from(bits: $underlying) -> Self {
573 Self::$try_from(bits).expect("Bitset contains invalid variants.")
574 }
575
576 #[doc = "Attempts to constructs a bitset from a `"]
577 #[doc = $underlying_str]
578 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
579 method will return `None`."]
580 #[inline(always)]
581 pub fn $try_from(bits: $underlying) -> Option<Self> {
582 let bits = T::Repr::$from_fn_opt(bits);
583 let mask = T::ALL_BITS;
584 bits.and_then(|bits| if bits.and_not(mask).is_empty() {
585 Some(EnumSet { repr: bits })
586 } else {
587 None
588 })
589 }
590
591 #[doc = "Constructs a bitset from a `"]
592 #[doc = $underlying_str]
593 #[doc = "`, ignoring bits that do not correspond to a variant."]
594 #[inline(always)]
595 pub fn $from_truncated(bits: $underlying) -> Self {
596 let mask = Self::all().$to_truncated();
597 let bits = <T::Repr as EnumSetTypeRepr>::$from_fn(bits & mask);
598 EnumSet { repr: bits }
599 }
600
601 #[doc = "Constructs a bitset from a `"]
602 #[doc = $underlying_str]
603 #[doc = "`, without checking for invalid bits."]
604 #[inline(always)]
611 pub unsafe fn $from_unchecked(bits: $underlying) -> Self {
612 EnumSet { repr: <T::Repr as EnumSetTypeRepr>::$from_fn(bits) }
613 }
614 )*}
615 }
616}
617conversion_impls! {
618 for_num!(u8, "u8",
619 from_u8 to_u8 from_u8_opt to_u8_opt,
620 from_u8 try_from_u8 from_u8_truncated from_u8_unchecked,
621 as_u8 try_as_u8 as_u8_truncated);
622 for_num!(u16, "u16",
623 from_u16 to_u16 from_u16_opt to_u16_opt,
624 from_u16 try_from_u16 from_u16_truncated from_u16_unchecked,
625 as_u16 try_as_u16 as_u16_truncated);
626 for_num!(u32, "u32",
627 from_u32 to_u32 from_u32_opt to_u32_opt,
628 from_u32 try_from_u32 from_u32_truncated from_u32_unchecked,
629 as_u32 try_as_u32 as_u32_truncated);
630 for_num!(u64, "u64",
631 from_u64 to_u64 from_u64_opt to_u64_opt,
632 from_u64 try_from_u64 from_u64_truncated from_u64_unchecked,
633 as_u64 try_as_u64 as_u64_truncated);
634 for_num!(u128, "u128",
635 from_u128 to_u128 from_u128_opt to_u128_opt,
636 from_u128 try_from_u128 from_u128_truncated from_u128_unchecked,
637 as_u128 try_as_u128 as_u128_truncated);
638 for_num!(usize, "usize",
639 from_usize to_usize from_usize_opt to_usize_opt,
640 from_usize try_from_usize from_usize_truncated from_usize_unchecked,
641 as_usize try_as_usize as_usize_truncated);
642}
643
644impl<T: EnumSetType> EnumSet<T> {
645 pub fn as_array<const O: usize>(&self) -> [u64; O] {
649 self.try_as_array()
650 .expect("Bitset will not fit into this type.")
651 }
652
653 pub fn try_as_array<const O: usize>(&self) -> Option<[u64; O]> {
658 self.repr.to_u64_array_opt()
659 }
660
661 pub fn as_array_truncated<const O: usize>(&self) -> [u64; O] {
666 self.repr.to_u64_array()
667 }
668
669 pub fn from_array<const O: usize>(v: [u64; O]) -> Self {
673 Self::try_from_array(v).expect("Bitset contains invalid variants.")
674 }
675
676 pub fn try_from_array<const O: usize>(bits: [u64; O]) -> Option<Self> {
680 let bits = T::Repr::from_u64_array_opt::<O>(bits);
681 let mask = T::ALL_BITS;
682 bits.and_then(|bits| {
683 if bits.and_not(mask).is_empty() {
684 Some(EnumSet { repr: bits })
685 } else {
686 None
687 }
688 })
689 }
690
691 pub fn from_array_truncated<const O: usize>(bits: [u64; O]) -> Self {
693 let bits = T::Repr::from_u64_array(bits) & T::ALL_BITS;
694 EnumSet { repr: bits }
695 }
696
697 #[inline(always)]
705 pub unsafe fn from_array_unchecked<const O: usize>(bits: [u64; O]) -> Self {
706 EnumSet { repr: T::Repr::from_u64_array(bits) }
707 }
708
709 #[cfg(feature = "alloc")]
711 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
712 pub fn to_vec(&self) -> alloc::vec::Vec<u64> {
713 let mut vec = alloc::vec![0; T::Repr::PREFERRED_ARRAY_LEN];
714 self.repr.to_u64_slice(&mut vec);
715 vec
716 }
717
718 pub fn copy_into_slice(&self, data: &mut [u64]) {
722 self.try_copy_into_slice(data)
723 .expect("Bitset will not fit into slice.")
724 }
725
726 #[must_use]
731 pub fn try_copy_into_slice(&self, data: &mut [u64]) -> Option<()> {
732 self.repr.to_u64_slice_opt(data)
733 }
734
735 pub fn copy_into_slice_truncated(&self, data: &mut [u64]) {
740 self.repr.to_u64_slice(data)
741 }
742
743 pub fn from_slice(v: &[u64]) -> Self {
747 Self::try_from_slice(v).expect("Bitset contains invalid variants.")
748 }
749
750 pub fn try_from_slice(bits: &[u64]) -> Option<Self> {
754 let bits = T::Repr::from_u64_slice_opt(bits);
755 let mask = T::ALL_BITS;
756 bits.and_then(|bits| {
757 if bits.and_not(mask).is_empty() {
758 Some(EnumSet { repr: bits })
759 } else {
760 None
761 }
762 })
763 }
764
765 pub fn from_slice_truncated(bits: &[u64]) -> Self {
767 let bits = T::Repr::from_u64_slice(bits) & T::ALL_BITS;
768 EnumSet { repr: bits }
769 }
770
771 #[inline(always)]
779 pub unsafe fn from_slice_unchecked(bits: &[u64]) -> Self {
780 EnumSet { repr: T::Repr::from_u64_slice(bits) }
781 }
782}
783
784impl<T: EnumSetType, const N: usize> From<[T; N]> for EnumSet<T> {
785 fn from(value: [T; N]) -> Self {
786 let mut new = EnumSet::new();
787 for elem in value {
788 new.insert(elem);
789 }
790 new
791 }
792}
793#[derive(Clone, Debug)]
798pub struct EnumSetIter<T: EnumSetType> {
799 iter: <T::Repr as EnumSetTypeRepr>::Iter,
800}
801impl<T: EnumSetType> EnumSetIter<T> {
802 fn new(set: EnumSet<T>) -> EnumSetIter<T> {
803 EnumSetIter { iter: set.repr.iter() }
804 }
805}
806
807impl<T: EnumSetType> EnumSet<T> {
808 pub fn iter(&self) -> EnumSetIter<T> {
814 EnumSetIter::new(*self)
815 }
816}
817
818impl<T: EnumSetType> Iterator for EnumSetIter<T> {
819 type Item = T;
820
821 fn next(&mut self) -> Option<Self::Item> {
822 self.iter
823 .next()
824 .map(|x| unsafe { T::enum_from_u32_checked(x) })
825 }
826 fn size_hint(&self) -> (usize, Option<usize>) {
827 self.iter.size_hint()
828 }
829}
830
831impl<T: EnumSetType> DoubleEndedIterator for EnumSetIter<T> {
832 fn next_back(&mut self) -> Option<Self::Item> {
833 self.iter
834 .next_back()
835 .map(|x| unsafe { T::enum_from_u32_checked(x) })
836 }
837}
838
839impl<T: EnumSetType> ExactSizeIterator for EnumSetIter<T> {}
840
841impl<T: EnumSetType> Extend<T> for EnumSet<T> {
842 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
843 iter.into_iter().for_each(|v| {
844 self.insert(v);
845 });
846 }
847}
848
849impl<'a, T: EnumSetType> Extend<&'a T> for EnumSet<T> {
850 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
851 iter.into_iter().for_each(|v| {
852 self.insert(*v);
853 });
854 }
855}
856
857impl<T: EnumSetType> FromIterator<T> for EnumSet<T> {
858 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
859 let mut set = EnumSet::default();
860 set.extend(iter);
861 set
862 }
863}
864
865impl<T: EnumSetType> Extend<EnumSet<T>> for EnumSet<T> {
866 fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
867 iter.into_iter().for_each(|v| {
868 self.insert_all(v);
869 });
870 }
871}
872
873impl<'a, T: EnumSetType> Extend<&'a EnumSet<T>> for EnumSet<T> {
874 fn extend<I: IntoIterator<Item = &'a EnumSet<T>>>(&mut self, iter: I) {
875 iter.into_iter().for_each(|v| {
876 self.insert_all(*v);
877 });
878 }
879}
880
881impl<T: EnumSetType> FromIterator<EnumSet<T>> for EnumSet<T> {
882 fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
883 let mut set = EnumSet::default();
884 set.extend(iter);
885 set
886 }
887}
888
889impl<T: EnumSetType> IntoIterator for EnumSet<T> {
890 type Item = T;
891 type IntoIter = EnumSetIter<T>;
892
893 fn into_iter(self) -> Self::IntoIter {
894 self.iter()
895 }
896}
897impl<T: EnumSetType> Sum for EnumSet<T> {
898 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
899 iter.fold(EnumSet::empty(), |a, v| a | v)
900 }
901}
902impl<'a, T: EnumSetType> Sum<&'a EnumSet<T>> for EnumSet<T> {
903 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
904 iter.fold(EnumSet::empty(), |a, v| a | *v)
905 }
906}
907impl<T: EnumSetType> Sum<T> for EnumSet<T> {
908 fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
909 iter.fold(EnumSet::empty(), |a, v| a | v)
910 }
911}
912impl<'a, T: EnumSetType> Sum<&'a T> for EnumSet<T> {
913 fn sum<I: Iterator<Item = &'a T>>(iter: I) -> Self {
914 iter.fold(EnumSet::empty(), |a, v| a | *v)
915 }
916}
917