use std::marker::PhantomData;
pub trait Named {
const NAME: &'static str;
const BACKWARD_COMPATIBILITY_ALIASES: &'static [&'static str] = &[];
}
pub trait ParameterSetConformant {
type ParameterSet;
fn is_conformant(&self, parameter_set: &Self::ParameterSet) -> bool;
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct EnumSet<T> {
mask: u128,
_phantom: PhantomData<T>,
}
impl<T> Default for EnumSet<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> EnumSet<T> {
pub const fn new() -> Self {
Self {
mask: 0,
_phantom: PhantomData,
}
}
}
impl<T> EnumSet<T>
where
T: Into<usize> + Copy,
{
pub fn contains(&self, value: T) -> bool {
let index = value.into();
if index < 128 {
(self.mask & (1 << index)) != 0
} else {
false
}
}
pub fn insert(&mut self, value: T) {
let index = value.into();
assert!(index < 128, "Config index too large for u128");
self.mask |= 1 << index;
}
pub fn remove(&mut self, value: T) {
let index = value.into();
if index < 128 {
self.mask &= !(1 << index);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, Clone, Copy, PartialEq)]
enum Color {
Red = 0,
Green = 1,
Blue = 2,
}
impl From<Color> for usize {
fn from(c: Color) -> Self {
c as Self
}
}
#[test]
fn insert_and_contains() {
let mut set = EnumSet::new();
assert!(!set.contains(Color::Red));
set.insert(Color::Red);
set.insert(Color::Blue);
assert!(set.contains(Color::Red));
assert!(!set.contains(Color::Green));
assert!(set.contains(Color::Blue));
}
#[test]
fn remove() {
let mut set = EnumSet::new();
set.insert(Color::Red);
set.insert(Color::Green);
set.remove(Color::Red);
assert!(!set.contains(Color::Red));
assert!(set.contains(Color::Green));
}
#[test]
fn contains_out_of_range_returns_false() {
#[derive(Debug, Clone, Copy)]
struct Big;
impl From<Big> for usize {
fn from(_: Big) -> Self {
200 }
}
let set = EnumSet::new();
assert!(!set.contains(Big));
}
}