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