1use std::fmt;
2use std::fmt::Debug;
3use std::fmt::Formatter;
4use std::marker::PhantomData;
5use std::slice;
6
7use crate::set::set_ref::OrdinalSetRef;
8use crate::Ordinal;
9
10pub struct Iter64<T> {
12 set: u64,
13 _phantom: PhantomData<T>,
14}
15
16impl<T: Ordinal> Iterator for Iter64<T> {
17 type Item = T;
18
19 #[inline]
20 fn next(&mut self) -> Option<Self::Item> {
21 let ordinal = self.set.trailing_zeros();
22 if ordinal == u64::BITS {
23 None
24 } else {
25 self.set &= !(1 << ordinal);
26 Some(T::from_ordinal(ordinal as usize).unwrap())
27 }
28 }
29
30 #[inline]
31 fn size_hint(&self) -> (usize, Option<usize>) {
32 let len = self.len();
33 (len, Some(len))
34 }
35}
36
37impl<T: Ordinal> ExactSizeIterator for Iter64<T> {
38 #[inline]
39 fn len(&self) -> usize {
40 self.set.count_ones() as usize
41 }
42}
43
44impl<T: Ordinal> DoubleEndedIterator for Iter64<T> {
45 #[inline]
46 fn next_back(&mut self) -> Option<Self::Item> {
47 let ordinal = (u64::BITS - 1).checked_sub(self.set.leading_zeros())?;
48 self.set &= !(1 << ordinal);
49 Some(T::from_ordinal(ordinal as usize).unwrap())
50 }
51}
52
53impl<T> Clone for Iter64<T> {
54 #[inline]
55 fn clone(&self) -> Self {
56 Iter64 {
57 set: self.set,
58 _phantom: PhantomData,
59 }
60 }
61}
62
63impl<T: Ordinal + Debug> Debug for Iter64<T> {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 f.debug_list().entries(self.clone()).finish()
66 }
67}
68
69#[derive(Eq, PartialEq)]
74pub struct OrdinalSet64<T> {
75 set: u64,
76 _phantom: PhantomData<T>,
77}
78
79impl<T: Ordinal> OrdinalSet64<T> {
80 const ASSERT: () = {
81 assert!(T::ORDINAL_SIZE <= u64::BITS as usize);
82 };
83
84 #[inline]
86 pub const fn new() -> Self {
87 const { Self::ASSERT };
88 OrdinalSet64 {
89 set: 0,
90 _phantom: PhantomData,
91 }
92 }
93
94 fn as_ref(&self) -> OrdinalSetRef<'_, T> {
95 OrdinalSetRef::new(slice::from_ref(&self.set))
96 }
97
98 #[inline]
100 pub fn all() -> Self {
101 const { Self::ASSERT };
102 OrdinalSet64 {
103 set: (1 << T::ORDINAL_SIZE) - 1,
104 _phantom: PhantomData,
105 }
106 }
107
108 #[inline]
110 pub fn insert(&mut self, ordinal: T) -> bool {
111 const { Self::ASSERT };
112 let r = !self.contains(&ordinal);
113 self.set |= 1 << ordinal.ordinal();
114 r
115 }
116
117 #[inline]
119 pub fn iter(&self) -> Iter64<T> {
120 const { Self::ASSERT };
121 Iter64 {
122 set: self.set,
123 _phantom: PhantomData,
124 }
125 }
126
127 #[inline]
129 pub fn contains(&self, ordinal: &T) -> bool {
130 const { Self::ASSERT };
131 self.set & (1 << ordinal.ordinal()) != 0
132 }
133}
134
135impl<T: Ordinal> Default for OrdinalSet64<T> {
136 fn default() -> Self {
137 OrdinalSet64::new()
138 }
139}
140
141impl<T: Ordinal> FromIterator<T> for OrdinalSet64<T> {
142 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
143 let mut set = OrdinalSet64::new();
144 for ordinal in iter {
145 set.set |= 1 << ordinal.ordinal();
146 }
147 set
148 }
149}
150
151impl<T> Clone for OrdinalSet64<T> {
152 fn clone(&self) -> Self {
153 OrdinalSet64 {
154 set: self.set,
155 _phantom: PhantomData,
156 }
157 }
158}
159
160impl<T: Ordinal + Debug> Debug for OrdinalSet64<T> {
161 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
162 Debug::fmt(&self.as_ref(), f)
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use crate::set::OrdinalSet64;
169 use crate::tests::util::test_exact_size_iterator;
170 use crate::tests::util::Example4;
171
172 #[test]
179 fn test_all() {
180 let set = OrdinalSet64::<Example4>::all();
181 assert_eq!(set.set, 0b1111);
182 }
183
184 #[quickcheck]
185 fn qc_iterator(mut values: Vec<Example4>) -> bool {
186 let set = OrdinalSet64::from_iter(values.iter().copied());
187 values.sort();
188 values.dedup();
189 set.iter().collect::<Vec<_>>() == values
190 }
191
192 #[quickcheck]
193 fn qc_double_ended_iterator(mut values: Vec<Example4>) -> bool {
194 let set = OrdinalSet64::from_iter(values.iter().copied());
195 values.sort();
196 values.dedup();
197 set.iter().rev().collect::<Vec<_>>() == values.into_iter().rev().collect::<Vec<_>>()
198 }
199
200 #[quickcheck]
201 fn qc_exact_size_iterator(values: Vec<Example4>) {
202 test_exact_size_iterator(OrdinalSet64::from_iter(values).iter());
203 }
204}