1use takparse::Color;
2
3type BitVec = u64;
4
5#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
6pub struct Colors {
7 bits: BitVec,
8}
9
10impl Default for Colors {
11 fn default() -> Self {
12 Self { bits: 1 }
13 }
14}
15
16impl Colors {
17 #[inline]
18 #[must_use]
19 pub const fn of_one(color: Color) -> Self {
20 Self {
21 bits: 0b10 + from_color(color),
22 }
23 }
24
25 #[inline]
26 #[must_use]
27 pub const fn is_empty(self) -> bool {
28 self.bits == 1
29 }
30
31 #[inline]
32 #[must_use]
33 pub const fn len(self) -> u32 {
34 BitVec::BITS - (self.bits.leading_zeros() + 1)
35 }
36
37 #[inline]
38 #[must_use]
39 pub const fn top(self) -> Option<Color> {
40 if self.is_empty() {
41 return None;
42 }
43 Some(to_color(self.bits & 1))
44 }
45
46 #[inline]
47 pub fn push(&mut self, color: Color) {
48 self.bits = (self.bits << 1) | BitVec::from(color == Color::White);
49 }
50
51 #[inline]
52 pub fn pop(&mut self) -> Option<Color> {
53 if self.is_empty() {
54 return None;
55 }
56 let color = to_color(self.bits & 1);
57 self.bits >>= 1;
58 Some(color)
59 }
60
61 #[inline]
62 pub fn take(&mut self, amount: u32) -> Option<Self> {
63 if amount > self.len() {
64 return None;
65 }
66 let mask: BitVec = !(!0 << amount);
67 let bits = (1 << amount) | (self.bits & mask);
68 let taken = Self { bits };
69 self.bits >>= amount;
70 Some(taken)
71 }
72
73 #[inline]
74 #[must_use]
75 pub const fn reverse(self) -> Self {
76 let len = self.len();
77 let bits = (1 << len) | (self.bits.reverse_bits() >> (BitVec::BITS - len));
78 Self { bits }
79 }
80}
81
82impl IntoIterator for Colors {
83 type IntoIter = ColorsIter;
84 type Item = Color;
85
86 #[inline]
87 fn into_iter(self) -> Self::IntoIter {
88 ColorsIter(self.reverse())
89 }
90}
91
92pub struct ColorsIter(Colors);
93
94impl Iterator for ColorsIter {
95 type Item = Color;
96
97 #[inline]
98 fn next(&mut self) -> Option<Self::Item> {
99 self.0.pop()
100 }
101
102 #[inline]
103 fn size_hint(&self) -> (usize, Option<usize>) {
104 let len = self.0.len() as usize;
105 (len, Some(len))
106 }
107}
108
109const fn to_color(n: BitVec) -> Color {
110 if n == 0 {
111 Color::Black
112 } else {
113 Color::White
114 }
115}
116
117const fn from_color(color: Color) -> BitVec {
118 match color {
119 Color::White => 1,
120 Color::Black => 0,
121 }
122}
123
124impl FromIterator<Color> for Colors {
125 fn from_iter<T: IntoIterator<Item = Color>>(iter: T) -> Self {
126 let mut colors = Self::default();
127 for color in iter {
128 colors.push(color);
129 }
130 colors
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use takparse::Color;
137
138 use super::{from_color, to_color, Colors};
139
140 #[test]
141 fn color_num() {
142 assert_eq!(Color::White, to_color(from_color(Color::White)));
143 assert_eq!(Color::Black, to_color(from_color(Color::Black)));
144 assert_eq!(from_color(Color::White), 1);
145 assert_eq!(from_color(Color::Black), 0);
146 }
147
148 #[test]
149 fn push_pop() {
150 let mut colors = Colors::default();
151 colors.push(Color::White);
152 colors.push(Color::White);
153 colors.push(Color::Black);
154 colors.push(Color::White);
155 colors.push(Color::Black);
156
157 assert_eq!(colors.len(), 5);
158 assert_eq!(colors.pop(), Some(Color::Black));
159 assert_eq!(colors.pop(), Some(Color::White));
160 assert_eq!(colors.pop(), Some(Color::Black));
161 assert_eq!(colors.pop(), Some(Color::White));
162 assert_eq!(colors.pop(), Some(Color::White));
163 assert_eq!(colors.pop(), None);
164 }
165
166 #[test]
167 fn iter() {
168 let mut colors = Colors::of_one(Color::White);
169 colors.push(Color::Black);
170 colors.push(Color::Black);
171 colors.push(Color::White);
172 colors.push(Color::White);
173 colors.push(Color::Black);
174
175 assert_eq!(colors.len(), 6);
176 let v: Vec<_> = colors.into_iter().collect();
177 assert_eq!(v, [
178 Color::White,
179 Color::Black,
180 Color::Black,
181 Color::White,
182 Color::White,
183 Color::Black
184 ]);
185 }
186
187 #[test]
188 fn take() {
189 let mut colors = Colors::of_one(Color::White);
190 colors.push(Color::Black);
191 colors.push(Color::White);
192 colors.push(Color::Black);
193 colors.push(Color::Black);
194 colors.push(Color::White);
195
196 assert_eq!(colors.len(), 6);
197 let mut a = colors.take(5).unwrap();
198 assert_eq!(colors.len(), 1);
199 assert_eq!(a.len(), 5);
200
201 assert_eq!(a.pop(), Some(Color::White));
202 assert_eq!(a.pop(), Some(Color::Black));
203 assert_eq!(a.pop(), Some(Color::Black));
204 assert_eq!(a.pop(), Some(Color::White));
205 assert_eq!(a.pop(), Some(Color::Black));
206 assert_eq!(a.pop(), None);
207
208 assert_eq!(colors.pop(), Some(Color::White));
209 assert_eq!(colors.pop(), None);
210 }
211
212 #[test]
213 fn reverse() {
214 let mut colors = Colors::of_one(Color::White);
215 colors.push(Color::White);
216 colors.push(Color::Black);
217 colors.push(Color::Black);
218 colors.push(Color::Black);
219 colors.push(Color::White);
220
221 assert_eq!(colors.len(), 6);
222 assert_eq!(colors, colors.reverse().reverse());
223 let v: Vec<_> = colors.reverse().into_iter().collect();
224 assert_eq!(v, [
225 Color::White,
226 Color::Black,
227 Color::Black,
228 Color::Black,
229 Color::White,
230 Color::White
231 ]);
232
233 let mut iter = colors.into_iter();
235 let mut reverse = colors.reverse();
236 assert_eq!(reverse.len(), 6);
237 while let (Some(x), Some(y)) = (iter.next(), reverse.pop()) {
238 assert_eq!(x, y);
239 }
240 assert_eq!(iter.count(), 0);
241 assert!(reverse.is_empty());
242 }
243}