pub mod __internal {
use super::*;
- /// A struct used to type check [`enum_set!`].
- pub struct EnumSetSameTypeHack<'a, T: EnumSetType + 'static> {
- pub unified: &'a [T],
- pub enum_set: EnumSet<T>,
- }
-
/// A reexport of core to allow our macros to be generic to std vs core.
pub use ::core as core_export;
/// The syntax used is `enum_set!(Type::A | Type::B | Type::C)`. Each variant must be of the same
/// type, or a error will occur at compile-time.
///
+/// This macro accepts trailing `|`s to allow easier use in other macros.
+///
/// # Examples
///
/// ```rust
/// ```
#[macro_export]
macro_rules! enum_set {
- () => {
+ ($(|)*) => {
$crate::EnumSet { __enumset_underlying: 0 }
};
- ($($value:path)|* $(|)*) => {
- $crate::__internal::EnumSetSameTypeHack {
- unified: &[$($value,)*],
- enum_set: $crate::EnumSet {
- __enumset_underlying: 0 $(| (1 << ($value as u32)))*
- },
- }.enum_set
+ ($value:path $(|)*) => {
+ $value.__impl_enumset_internal__const_only()
+ };
+ ($value:path | $($rest:path)|* $(|)*) => {
+ {
+ #[allow(deprecated)] let value = $value.__impl_enumset_internal__const_only();
+ $(#[allow(deprecated)] let value = $rest.__impl_enumset_internal__const_merge(value);)*
+ value
+ }
};
}
quote!((*self as u32) == (*other as u32))
};
+ // used in the enum_set! macro `const fn`s.
+ let self_as_repr_mask = if is_uninhabited {
+ quote! { 0 } // impossible anyway
+ } else {
+ quote! { 1 << self as #repr }
+ };
+
quote! {
unsafe impl #enumset::__internal::EnumSetTypePrivate for #name {
type Repr = #repr;
}
impl #core::marker::Copy for #name { }
+ impl #name {
+ /// Creates a new enumset with only this variant.
+ #[deprecated(note = "This method is an internal implementation detail generated by \
+ the `enumset` crate's procedural macro. It should not be used \
+ directly. Use `EnumSet::only` instead.")]
+ #[doc(hidden)]
+ pub const fn __impl_enumset_internal__const_only(self) -> EnumSet<#name> {
+ EnumSet { __enumset_underlying: #self_as_repr_mask }
+ }
+
+ /// Creates a new enumset with this variant added.
+ #[deprecated(note = "This method is an internal implementation detail generated by \
+ the `enumset` crate's procedural macro. It should not be used \
+ directly. Use the `|` operator instead.")]
+ #[doc(hidden)]
+ pub const fn __impl_enumset_internal__const_merge(
+ self, chain: EnumSet<#name>,
+ ) -> EnumSet<#name> {
+ EnumSet { __enumset_underlying: chain.__enumset_underlying | #self_as_repr_mask }
+ }
+ }
+
#ops
}
}