char_bag.rs

 1use std::iter::FromIterator;
 2
 3#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
 4pub struct CharBag(u64);
 5
 6impl CharBag {
 7    pub const fn is_superset(self, other: CharBag) -> bool {
 8        self.0 & other.0 == other.0
 9    }
10
11    const fn insert(&mut self, c: char) {
12        let c = c.to_ascii_lowercase();
13        if c.is_ascii_lowercase() {
14            let mut count = self.0;
15            let idx = c as u8 - b'a';
16            count >>= idx * 2;
17            count = ((count << 1) | 1) & 3;
18            count <<= idx * 2;
19            self.0 |= count;
20        } else if c.is_ascii_digit() {
21            let idx = c as u8 - b'0';
22            self.0 |= 1 << (idx + 52);
23        } else if c == '-' {
24            self.0 |= 1 << 62;
25        }
26    }
27}
28
29impl Extend<char> for CharBag {
30    fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
31        for c in iter {
32            self.insert(c);
33        }
34    }
35}
36
37impl FromIterator<char> for CharBag {
38    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
39        let mut result = Self::default();
40        result.extend(iter);
41        result
42    }
43}
44
45impl From<&str> for CharBag {
46    fn from(s: &str) -> Self {
47        let mut bag = Self(0);
48        for c in s.chars() {
49            bag.insert(c);
50        }
51        bag
52    }
53}
54
55impl From<&[char]> for CharBag {
56    fn from(chars: &[char]) -> Self {
57        let mut bag = Self(0);
58        for c in chars {
59            bag.insert(*c);
60        }
61        bag
62    }
63}