1use crate::repr::EnumSetTypeRepr;
2use crate::traits::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#[cfg_attr(
115 not(feature = "serde"),
116 doc = "\n\n",
117 doc = "[`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html\n",
118 doc = "[`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html\n"
119)]
120#[derive(Copy, Clone, PartialEq, Eq)]
121#[repr(transparent)]
122pub struct EnumSet<T: EnumSetType> {
123 #[doc(hidden)]
124 pub __priv_repr: T::Repr,
127}
128
129impl<T: EnumSetType> EnumSet<T> {
131 const EMPTY_REPR: Self = EnumSet { __priv_repr: T::Repr::EMPTY };
132 const ALL_REPR: Self = EnumSet { __priv_repr: T::ALL_BITS };
133
134 #[inline(always)]
136 pub const fn new() -> Self {
137 Self::EMPTY_REPR
138 }
139
140 #[inline(always)]
142 pub fn only(t: T) -> Self {
143 let mut set = Self::new();
144 set.insert(t);
145 set
146 }
147
148 #[inline(always)]
152 pub const fn empty() -> Self {
153 Self::EMPTY_REPR
154 }
155
156 #[inline(always)]
158 pub const fn all() -> Self {
159 Self::ALL_REPR
160 }
161
162 #[inline(always)]
168 pub const fn bit_width() -> u32 {
169 T::BIT_WIDTH
170 }
171
172 #[inline(always)]
177 pub const fn variant_count() -> u32 {
178 T::VARIANT_COUNT
179 }
180
181 #[inline(always)]
183 pub fn len(&self) -> usize {
184 self.__priv_repr.count_ones() as usize
185 }
186 #[inline(always)]
188 pub fn is_empty(&self) -> bool {
189 self.__priv_repr.is_empty()
190 }
191 #[inline(always)]
193 pub fn clear(&mut self) {
194 self.__priv_repr = T::Repr::EMPTY;
195 }
196
197 #[inline(always)]
200 pub fn is_disjoint(&self, other: Self) -> bool {
201 (*self & other).is_empty()
202 }
203 #[inline(always)]
206 pub fn is_superset(&self, other: Self) -> bool {
207 (*self & other).__priv_repr == other.__priv_repr
208 }
209 #[inline(always)]
212 pub fn is_subset(&self, other: Self) -> bool {
213 other.is_superset(*self)
214 }
215
216 #[inline(always)]
218 pub fn union(&self, other: Self) -> Self {
219 EnumSet { __priv_repr: self.__priv_repr | other.__priv_repr }
220 }
221 #[inline(always)]
223 pub fn intersection(&self, other: Self) -> Self {
224 EnumSet { __priv_repr: self.__priv_repr & other.__priv_repr }
225 }
226 #[inline(always)]
228 pub fn difference(&self, other: Self) -> Self {
229 EnumSet { __priv_repr: self.__priv_repr.and_not(other.__priv_repr) }
230 }
231 #[inline(always)]
234 pub fn symmetrical_difference(&self, other: Self) -> Self {
235 EnumSet { __priv_repr: self.__priv_repr ^ other.__priv_repr }
236 }
237 #[inline(always)]
239 pub fn complement(&self) -> Self {
240 EnumSet { __priv_repr: !self.__priv_repr & T::ALL_BITS }
241 }
242
243 #[inline(always)]
245 pub fn contains(&self, value: T) -> bool {
246 self.__priv_repr.has_bit(value.enum_into_u32())
247 }
248
249 #[inline(always)]
255 pub fn insert(&mut self, value: T) -> bool {
256 let contains = !self.contains(value);
257 self.__priv_repr.add_bit(value.enum_into_u32());
258 contains
259 }
260 #[inline(always)]
262 pub fn remove(&mut self, value: T) -> bool {
263 let contains = self.contains(value);
264 self.__priv_repr.remove_bit(value.enum_into_u32());
265 contains
266 }
267
268 #[inline(always)]
270 pub fn insert_all(&mut self, other: Self) {
271 self.__priv_repr = self.__priv_repr | other.__priv_repr
272 }
273 #[inline(always)]
275 pub fn remove_all(&mut self, other: Self) {
276 self.__priv_repr = self.__priv_repr.and_not(other.__priv_repr);
277 }
278}
279
280#[doc(hidden)]
281impl<T: EnumSetType> EnumSet<T> {
282 #[deprecated(note = "This method is an internal implementation detail generated by the \
284 `enumset` crate's procedural macro. It should not be used directly.")]
285 #[doc(hidden)]
286 #[allow(non_snake_case)]
287 pub const fn __impl_enumset_internal__const_helper(&self) -> T::ConstHelper {
288 T::CONST_HELPER_INSTANCE
289 }
290
291 #[deprecated(note = "This method is an internal implementation detail generated by the \
293 `enumset` crate's procedural macro. It should not be used directly.")]
294 #[doc(hidden)]
295 #[allow(non_snake_case)]
296 pub const fn __impl_enumset_internal__const_only(self) -> Self {
297 self
298 }
299}
300
301impl<T: EnumSetType> Default for EnumSet<T> {
302 fn default() -> Self {
304 Self::new()
305 }
306}
307
308impl<T: EnumSetType, O: Into<EnumSet<T>>> Sub<O> for EnumSet<T> {
309 type Output = Self;
310 #[inline(always)]
311 fn sub(self, other: O) -> Self::Output {
312 self.difference(other.into())
313 }
314}
315impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAnd<O> for EnumSet<T> {
316 type Output = Self;
317 #[inline(always)]
318 fn bitand(self, other: O) -> Self::Output {
319 self.intersection(other.into())
320 }
321}
322impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOr<O> for EnumSet<T> {
323 type Output = Self;
324 #[inline(always)]
325 fn bitor(self, other: O) -> Self::Output {
326 self.union(other.into())
327 }
328}
329impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXor<O> for EnumSet<T> {
330 type Output = Self;
331 #[inline(always)]
332 fn bitxor(self, other: O) -> Self::Output {
333 self.symmetrical_difference(other.into())
334 }
335}
336
337impl<T: EnumSetType, O: Into<EnumSet<T>>> SubAssign<O> for EnumSet<T> {
338 #[inline(always)]
339 fn sub_assign(&mut self, rhs: O) {
340 *self = *self - rhs;
341 }
342}
343impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAndAssign<O> for EnumSet<T> {
344 #[inline(always)]
345 fn bitand_assign(&mut self, rhs: O) {
346 *self = *self & rhs;
347 }
348}
349impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOrAssign<O> for EnumSet<T> {
350 #[inline(always)]
351 fn bitor_assign(&mut self, rhs: O) {
352 *self = *self | rhs;
353 }
354}
355impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXorAssign<O> for EnumSet<T> {
356 #[inline(always)]
357 fn bitxor_assign(&mut self, rhs: O) {
358 *self = *self ^ rhs;
359 }
360}
361
362impl<T: EnumSetType> Not for EnumSet<T> {
363 type Output = Self;
364 #[inline(always)]
365 fn not(self) -> Self::Output {
366 self.complement()
367 }
368}
369
370impl<T: EnumSetType> From<T> for EnumSet<T> {
371 fn from(t: T) -> Self {
372 EnumSet::only(t)
373 }
374}
375
376impl<T: EnumSetType> PartialEq<T> for EnumSet<T> {
377 fn eq(&self, other: &T) -> bool {
378 self.__priv_repr == EnumSet::only(*other).__priv_repr
379 }
380}
381
382impl<T: EnumSetType + Debug> Debug for EnumSet<T> {
383 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
384 f.write_str("EnumSet(")?;
386 let mut i = self.iter();
387 if let Some(v) = i.next() {
388 v.fmt(f)?;
389 for v in i {
390 f.write_str(" | ")?;
391 v.fmt(f)?;
392 }
393 }
394 f.write_str(")")?;
395 Ok(())
396 }
397}
398impl<T: EnumSetType + Display> Display for EnumSet<T> {
399 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
400 let mut i = self.iter();
401 if let Some(v) = i.next() {
402 v.fmt(f)?;
403 for v in i {
404 f.write_str(" | ")?;
405 v.fmt(f)?;
406 }
407 }
408 Ok(())
409 }
410}
411
412#[cfg(feature = "defmt")]
413impl<T: EnumSetType + defmt::Format> defmt::Format for EnumSet<T> {
414 fn format(&self, f: defmt::Formatter) {
415 let mut i = self.iter();
416 if let Some(v) = i.next() {
417 v.format(f);
418 let l = defmt::intern!(" | ");
419 for v in i {
420 l.format(f);
421 v.format(f);
422 }
423 }
424 }
425}
426
427#[allow(clippy::derived_hash_with_manual_eq)] impl<T: EnumSetType> Hash for EnumSet<T> {
429 fn hash<H: Hasher>(&self, state: &mut H) {
430 self.__priv_repr.hash(state)
431 }
432}
433#[allow(clippy::non_canonical_partial_ord_impl)]
434impl<T: EnumSetType> PartialOrd for EnumSet<T> {
435 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
436 self.__priv_repr.partial_cmp(&other.__priv_repr)
437 }
438}
439impl<T: EnumSetType> Ord for EnumSet<T> {
440 fn cmp(&self, other: &Self) -> Ordering {
441 self.__priv_repr.cmp(&other.__priv_repr)
442 }
443}
444
445#[cfg(feature = "serde")]
446impl<T: EnumSetType> Serialize for EnumSet<T> {
447 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
448 T::serialize(*self, serializer)
449 }
450}
451
452#[cfg(feature = "serde")]
453impl<'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
454 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
455 T::deserialize(deserializer)
456 }
457}
458impl<T: EnumSetType> EnumSet<T> {
463 #[deprecated = "Use `EnumSet::empty()` instead."]
467 pub const EMPTY: Self = Self::EMPTY_REPR;
468
469 #[deprecated = "Use `EnumSet::all()` instead."]
473 pub const ALL: Self = Self::ALL_REPR;
474}
475impl<T: EnumSetType + EnumSetTypeWithRepr> EnumSet<T> {
479 #[inline(always)]
487 pub const fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr {
488 self.__priv_repr
489 }
490
491 #[inline(always)]
504 pub unsafe fn from_repr_unchecked(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
505 Self { __priv_repr: bits }
506 }
507
508 #[inline(always)]
516 pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
517 Self::try_from_repr(bits).expect("Bitset contains invalid variants.")
518 }
519
520 #[inline(always)]
528 pub fn try_from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Option<Self> {
529 let mask = Self::all().__priv_repr;
530 if bits.and_not(mask).is_empty() {
531 Some(EnumSet { __priv_repr: bits })
532 } else {
533 None
534 }
535 }
536
537 #[inline(always)]
542 pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
543 let mask = Self::all().as_repr();
544 let bits = bits & mask;
545 EnumSet { __priv_repr: bits }
546 }
547}
548
549macro_rules! conversion_impls {
551 (
552 $(for_num!(
553 $underlying:ty, $underlying_str:expr,
554 $from_fn:ident $to_fn:ident $from_fn_opt:ident $to_fn_opt:ident,
555 $from:ident $try_from:ident $from_truncated:ident $from_unchecked:ident,
556 $to:ident $try_to:ident $to_truncated:ident
557 );)*
558 ) => {
559 impl<T: EnumSetType> EnumSet<T> {$(
560 #[doc = "Returns a `"]
561 #[doc = $underlying_str]
562 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
563 not fit in a `"]
564 #[doc = $underlying_str]
565 #[doc = "`, this method will panic."]
566 #[inline(always)]
567 pub fn $to(&self) -> $underlying {
568 self.$try_to().expect("Bitset will not fit into this type.")
569 }
570
571 #[doc = "Tries to return a `"]
572 #[doc = $underlying_str]
573 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
574 not fit in a `"]
575 #[doc = $underlying_str]
576 #[doc = "`, this method will panic."]
577 #[inline(always)]
578 pub fn $try_to(&self) -> Option<$underlying> {
579 EnumSetTypeRepr::$to_fn_opt(&self.__priv_repr)
580 }
581
582 #[doc = "Returns a truncated `"]
583 #[doc = $underlying_str]
584 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
585 not fit in a `"]
586 #[doc = $underlying_str]
587 #[doc = "`, this method will truncate any bits that don't fit."]
588 #[inline(always)]
589 pub fn $to_truncated(&self) -> $underlying {
590 EnumSetTypeRepr::$to_fn(&self.__priv_repr)
591 }
592
593 #[doc = "Constructs a bitset from a `"]
594 #[doc = $underlying_str]
595 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
596 method will panic."]
597 #[inline(always)]
598 pub fn $from(bits: $underlying) -> Self {
599 Self::$try_from(bits).expect("Bitset contains invalid variants.")
600 }
601
602 #[doc = "Attempts to constructs a bitset from a `"]
603 #[doc = $underlying_str]
604 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
605 method will return `None`."]
606 #[inline(always)]
607 pub fn $try_from(bits: $underlying) -> Option<Self> {
608 let bits = T::Repr::$from_fn_opt(bits);
609 let mask = T::ALL_BITS;
610 bits.and_then(|bits| if bits.and_not(mask).is_empty() {
611 Some(EnumSet { __priv_repr: bits })
612 } else {
613 None
614 })
615 }
616
617 #[doc = "Constructs a bitset from a `"]
618 #[doc = $underlying_str]
619 #[doc = "`, ignoring bits that do not correspond to a variant."]
620 #[inline(always)]
621 pub fn $from_truncated(bits: $underlying) -> Self {
622 let mask = Self::all().$to_truncated();
623 let bits = <T::Repr as EnumSetTypeRepr>::$from_fn(bits & mask);
624 EnumSet { __priv_repr: bits }
625 }
626
627 #[doc = "Constructs a bitset from a `"]
628 #[doc = $underlying_str]
629 #[doc = "`, without checking for invalid bits."]
630 #[inline(always)]
637 pub unsafe fn $from_unchecked(bits: $underlying) -> Self {
638 EnumSet { __priv_repr: <T::Repr as EnumSetTypeRepr>::$from_fn(bits) }
639 }
640 )*}
641 }
642}
643conversion_impls! {
644 for_num!(u8, "u8",
645 from_u8 to_u8 from_u8_opt to_u8_opt,
646 from_u8 try_from_u8 from_u8_truncated from_u8_unchecked,
647 as_u8 try_as_u8 as_u8_truncated);
648 for_num!(u16, "u16",
649 from_u16 to_u16 from_u16_opt to_u16_opt,
650 from_u16 try_from_u16 from_u16_truncated from_u16_unchecked,
651 as_u16 try_as_u16 as_u16_truncated);
652 for_num!(u32, "u32",
653 from_u32 to_u32 from_u32_opt to_u32_opt,
654 from_u32 try_from_u32 from_u32_truncated from_u32_unchecked,
655 as_u32 try_as_u32 as_u32_truncated);
656 for_num!(u64, "u64",
657 from_u64 to_u64 from_u64_opt to_u64_opt,
658 from_u64 try_from_u64 from_u64_truncated from_u64_unchecked,
659 as_u64 try_as_u64 as_u64_truncated);
660 for_num!(u128, "u128",
661 from_u128 to_u128 from_u128_opt to_u128_opt,
662 from_u128 try_from_u128 from_u128_truncated from_u128_unchecked,
663 as_u128 try_as_u128 as_u128_truncated);
664 for_num!(usize, "usize",
665 from_usize to_usize from_usize_opt to_usize_opt,
666 from_usize try_from_usize from_usize_truncated from_usize_unchecked,
667 as_usize try_as_usize as_usize_truncated);
668}
669
670impl<T: EnumSetType> EnumSet<T> {
671 pub fn as_array<const O: usize>(&self) -> [u64; O] {
675 self.try_as_array()
676 .expect("Bitset will not fit into this type.")
677 }
678
679 pub fn try_as_array<const O: usize>(&self) -> Option<[u64; O]> {
684 self.__priv_repr.to_u64_array_opt()
685 }
686
687 pub fn as_array_truncated<const O: usize>(&self) -> [u64; O] {
692 self.__priv_repr.to_u64_array()
693 }
694
695 pub fn from_array<const O: usize>(v: [u64; O]) -> Self {
699 Self::try_from_array(v).expect("Bitset contains invalid variants.")
700 }
701
702 pub fn try_from_array<const O: usize>(bits: [u64; O]) -> Option<Self> {
706 let bits = T::Repr::from_u64_array_opt::<O>(bits);
707 let mask = T::ALL_BITS;
708 bits.and_then(|bits| {
709 if bits.and_not(mask).is_empty() {
710 Some(EnumSet { __priv_repr: bits })
711 } else {
712 None
713 }
714 })
715 }
716
717 pub fn from_array_truncated<const O: usize>(bits: [u64; O]) -> Self {
719 let bits = T::Repr::from_u64_array(bits) & T::ALL_BITS;
720 EnumSet { __priv_repr: bits }
721 }
722
723 #[inline(always)]
731 pub unsafe fn from_array_unchecked<const O: usize>(bits: [u64; O]) -> Self {
732 EnumSet { __priv_repr: T::Repr::from_u64_array(bits) }
733 }
734
735 #[cfg(feature = "alloc")]
737 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
738 pub fn to_vec(&self) -> alloc::vec::Vec<u64> {
739 let mut vec = alloc::vec![0; T::Repr::PREFERRED_ARRAY_LEN];
740 self.__priv_repr.to_u64_slice(&mut vec);
741 vec
742 }
743
744 pub fn copy_into_slice(&self, data: &mut [u64]) {
748 self.try_copy_into_slice(data)
749 .expect("Bitset will not fit into slice.")
750 }
751
752 #[must_use]
757 pub fn try_copy_into_slice(&self, data: &mut [u64]) -> Option<()> {
758 self.__priv_repr.to_u64_slice_opt(data)
759 }
760
761 pub fn copy_into_slice_truncated(&self, data: &mut [u64]) {
766 self.__priv_repr.to_u64_slice(data)
767 }
768
769 pub fn from_slice(v: &[u64]) -> Self {
773 Self::try_from_slice(v).expect("Bitset contains invalid variants.")
774 }
775
776 pub fn try_from_slice(bits: &[u64]) -> Option<Self> {
780 let bits = T::Repr::from_u64_slice_opt(bits);
781 let mask = T::ALL_BITS;
782 bits.and_then(|bits| {
783 if bits.and_not(mask).is_empty() {
784 Some(EnumSet { __priv_repr: bits })
785 } else {
786 None
787 }
788 })
789 }
790
791 pub fn from_slice_truncated(bits: &[u64]) -> Self {
793 let bits = T::Repr::from_u64_slice(bits) & T::ALL_BITS;
794 EnumSet { __priv_repr: bits }
795 }
796
797 #[inline(always)]
805 pub unsafe fn from_slice_unchecked(bits: &[u64]) -> Self {
806 EnumSet { __priv_repr: T::Repr::from_u64_slice(bits) }
807 }
808}
809#[derive(Clone, Debug)]
814pub struct EnumSetIter<T: EnumSetType> {
815 iter: <T::Repr as EnumSetTypeRepr>::Iter,
816}
817impl<T: EnumSetType> EnumSetIter<T> {
818 fn new(set: EnumSet<T>) -> EnumSetIter<T> {
819 EnumSetIter { iter: set.__priv_repr.iter() }
820 }
821}
822
823impl<T: EnumSetType> EnumSet<T> {
824 pub fn iter(&self) -> EnumSetIter<T> {
830 EnumSetIter::new(*self)
831 }
832}
833
834impl<T: EnumSetType> Iterator for EnumSetIter<T> {
835 type Item = T;
836
837 fn next(&mut self) -> Option<Self::Item> {
838 self.iter.next().map(|x| unsafe { T::enum_from_u32(x) })
839 }
840 fn size_hint(&self) -> (usize, Option<usize>) {
841 self.iter.size_hint()
842 }
843}
844
845impl<T: EnumSetType> DoubleEndedIterator for EnumSetIter<T> {
846 fn next_back(&mut self) -> Option<Self::Item> {
847 self.iter
848 .next_back()
849 .map(|x| unsafe { T::enum_from_u32(x) })
850 }
851}
852
853impl<T: EnumSetType> ExactSizeIterator for EnumSetIter<T> {}
854
855impl<T: EnumSetType> Extend<T> for EnumSet<T> {
856 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
857 iter.into_iter().for_each(|v| {
858 self.insert(v);
859 });
860 }
861}
862
863impl<T: EnumSetType> FromIterator<T> for EnumSet<T> {
864 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
865 let mut set = EnumSet::default();
866 set.extend(iter);
867 set
868 }
869}
870
871impl<T: EnumSetType> Extend<EnumSet<T>> for EnumSet<T> {
872 fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
873 iter.into_iter().for_each(|v| {
874 self.insert_all(v);
875 });
876 }
877}
878
879impl<T: EnumSetType> FromIterator<EnumSet<T>> for EnumSet<T> {
880 fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
881 let mut set = EnumSet::default();
882 set.extend(iter);
883 set
884 }
885}
886
887impl<T: EnumSetType> IntoIterator for EnumSet<T> {
888 type Item = T;
889 type IntoIter = EnumSetIter<T>;
890
891 fn into_iter(self) -> Self::IntoIter {
892 self.iter()
893 }
894}
895impl<T: EnumSetType> Sum for EnumSet<T> {
896 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
897 iter.fold(EnumSet::empty(), |a, v| a | v)
898 }
899}
900impl<'a, T: EnumSetType> Sum<&'a EnumSet<T>> for EnumSet<T> {
901 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
902 iter.fold(EnumSet::empty(), |a, v| a | *v)
903 }
904}
905impl<T: EnumSetType> Sum<T> for EnumSet<T> {
906 fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
907 iter.fold(EnumSet::empty(), |a, v| a | v)
908 }
909}
910impl<'a, T: EnumSetType> Sum<&'a T> for EnumSet<T> {
911 fn sum<I: Iterator<Item = &'a T>>(iter: I) -> Self {
912 iter.fold(EnumSet::empty(), |a, v| a | *v)
913 }
914}
915