1#[cfg(not(target_os = "emscripten"))]
6use crate::QDateTime;
7use crate::{QByteArray, QDate, QPersistentModelIndex, QString, QTime, QUrl, QUuid};
8use core::{marker::PhantomData, mem::MaybeUninit};
9use cxx::{type_id, ExternType};
10use std::fmt;
11
12#[repr(C)]
20pub struct QSet<T>
21where
22 T: QSetElement,
23{
24 _space: MaybeUninit<usize>,
25 _value: PhantomData<T>,
26}
27
28impl<T> Clone for QSet<T>
29where
30 T: QSetElement,
31{
32 fn clone(&self) -> Self {
34 T::clone(self)
35 }
36}
37
38impl<T> Default for QSet<T>
39where
40 T: QSetElement,
41{
42 fn default() -> Self {
44 T::default()
45 }
46}
47
48impl<T> Drop for QSet<T>
49where
50 T: QSetElement,
51{
52 fn drop(&mut self) {
54 T::drop(self);
55 }
56}
57
58impl<T> PartialEq for QSet<T>
59where
60 T: QSetElement + PartialEq,
61{
62 fn eq(&self, other: &Self) -> bool {
64 self.len() == other.len() && self.iter().all(|x| other.contains(x))
65 }
66}
67
68impl<T> Eq for QSet<T> where T: QSetElement + PartialEq {}
69
70impl<T> fmt::Debug for QSet<T>
71where
72 T: QSetElement + fmt::Debug,
73{
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 f.debug_set().entries(self.iter()).finish()
76 }
77}
78
79impl<T> QSet<T>
80where
81 T: QSetElement,
82{
83 pub fn clear(&mut self) {
85 T::clear(self);
86 }
87
88 pub fn contains(&self, value: &T) -> bool {
90 T::contains(self, value)
91 }
92
93 pub fn insert_clone(&mut self, value: &T) {
98 T::insert_clone(self, value);
99 }
100
101 pub fn is_empty(&self) -> bool {
103 T::len(self) == 0
104 }
105
106 pub fn iter(&self) -> Iter<'_, T> {
109 Iter {
110 set: self,
111 index: 0,
112 }
113 }
114
115 pub fn len(&self) -> isize {
117 T::len(self)
118 }
119
120 pub fn remove(&mut self, value: &T) -> bool {
123 T::remove(self, value)
124 }
125
126 pub fn reserve(&mut self, size: isize) {
134 T::reserve(self, size);
135 }
136
137 pub(crate) fn reserve_usize(&mut self, size: usize) {
139 if size != 0 {
140 T::reserve(self, isize::try_from(size).unwrap_or(isize::MAX));
141 }
142 }
143}
144
145impl<T> QSet<T>
146where
147 T: QSetElement + ExternType<Kind = cxx::kind::Trivial>,
148{
149 pub fn insert(&mut self, value: T) {
151 T::insert(self, value);
152 }
153}
154
155impl<'a, T> Extend<&'a T> for QSet<T>
156where
157 T: QSetElement,
158{
159 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
160 let iter = iter.into_iter();
161 self.reserve_usize(iter.size_hint().0);
162 for element in iter {
163 self.insert_clone(element);
164 }
165 }
166}
167
168impl<T> Extend<T> for QSet<T>
169where
170 T: QSetElement + ExternType<Kind = cxx::kind::Trivial>,
171{
172 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
173 let iter = iter.into_iter();
174 self.reserve_usize(iter.size_hint().0);
175 for element in iter {
176 self.insert(element);
177 }
178 }
179}
180
181impl<'a, T> FromIterator<&'a T> for QSet<T>
182where
183 T: QSetElement,
184{
185 fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self {
186 let mut qset = Self::default();
187 qset.extend(iter);
188 qset
189 }
190}
191
192impl<T> FromIterator<T> for QSet<T>
193where
194 T: QSetElement + ExternType<Kind = cxx::kind::Trivial>,
195{
196 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
197 let mut qset = Self::default();
198 qset.extend(iter);
199 qset
200 }
201}
202
203unsafe impl<T> ExternType for QSet<T>
204where
205 T: ExternType + QSetElement,
206{
207 type Id = T::TypeId;
208 type Kind = cxx::kind::Trivial;
209}
210
211pub struct Iter<'a, T>
212where
213 T: QSetElement,
214{
215 set: &'a QSet<T>,
216 index: isize,
217}
218
219impl<'a, T> Iterator for Iter<'a, T>
220where
221 T: QSetElement,
222{
223 type Item = &'a T;
224
225 fn next(&mut self) -> Option<Self::Item> {
226 if self.index < self.set.len() {
227 let next = unsafe { T::get_unchecked(self.set, self.index) };
228 self.index += 1;
229 Some(next)
230 } else {
231 None
232 }
233 }
234
235 fn size_hint(&self) -> (usize, Option<usize>) {
236 let len = self.len();
237 (len, Some(len))
238 }
239}
240
241impl<T> ExactSizeIterator for Iter<'_, T>
242where
243 T: QSetElement,
244{
245 fn len(&self) -> usize {
246 (self.set.len() - self.index) as usize
247 }
248}
249
250impl<'a, T> IntoIterator for &'a QSet<T>
251where
252 T: QSetElement,
253{
254 type Item = &'a T;
255
256 type IntoIter = Iter<'a, T>;
257
258 fn into_iter(self) -> Self::IntoIter {
259 self.iter()
260 }
261}
262
263pub trait QSetElement: Sized {
265 type TypeId;
266
267 fn clear(set: &mut QSet<Self>);
268 fn clone(set: &QSet<Self>) -> QSet<Self>;
269 fn contains(set: &QSet<Self>, value: &Self) -> bool;
270 fn default() -> QSet<Self>;
271 fn drop(set: &mut QSet<Self>);
272 unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self;
277 fn insert(set: &mut QSet<Self>, value: Self)
278 where
279 Self: ExternType<Kind = cxx::kind::Trivial>;
280 fn insert_clone(set: &mut QSet<Self>, value: &Self);
281 fn len(set: &QSet<Self>) -> isize;
282 fn remove(set: &mut QSet<Self>, value: &Self) -> bool;
283 fn reserve(set: &mut QSet<Self>, size: isize);
284}
285
286macro_rules! impl_qset_element {
287 ( $typeName:ty, $module:ident, $typeId:literal ) => {
288 mod $module;
289
290 impl QSetElement for $typeName {
291 type TypeId = type_id!($typeId);
292
293 fn clear(set: &mut QSet<Self>) {
294 set.cxx_clear()
295 }
296
297 fn clone(set: &QSet<Self>) -> QSet<Self> {
298 $module::clone(set)
299 }
300
301 fn contains(set: &QSet<Self>, value: &Self) -> bool {
302 set.cxx_contains(value)
303 }
304
305 fn default() -> QSet<Self> {
306 $module::default()
307 }
308
309 fn drop(set: &mut QSet<Self>) {
310 $module::drop(set);
311 }
312
313 unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self {
314 $module::get_unchecked(set, pos)
315 }
316
317 fn insert(set: &mut QSet<Self>, value: Self) {
318 $module::insert(set, &value);
319 }
320
321 fn insert_clone(set: &mut QSet<Self>, value: &Self) {
322 $module::insert(set, value);
323 }
324
325 fn len(set: &QSet<Self>) -> isize {
326 $module::len(set)
327 }
328
329 fn remove(set: &mut QSet<Self>, value: &Self) -> bool {
330 set.cxx_remove(value)
331 }
332
333 fn reserve(set: &mut QSet<Self>, size: isize) {
334 $module::reserve(set, size);
335 }
336 }
337 };
338}
339
340impl_qset_element!(bool, qset_bool, "QSet_bool");
341impl_qset_element!(f32, qset_f32, "QSet_f32");
342impl_qset_element!(f64, qset_f64, "QSet_f64");
343impl_qset_element!(i8, qset_i8, "QSet_i8");
344impl_qset_element!(i16, qset_i16, "QSet_i16");
345impl_qset_element!(i32, qset_i32, "QSet_i32");
346impl_qset_element!(i64, qset_i64, "QSet_i64");
347impl_qset_element!(QByteArray, qset_qbytearray, "QSet_QByteArray");
348impl_qset_element!(QDate, qset_qdate, "QSet_QDate");
349#[cfg(not(target_os = "emscripten"))]
350impl_qset_element!(QDateTime, qset_qdatetime, "QSet_QDateTime");
351impl_qset_element!(
352 QPersistentModelIndex,
353 qset_qpersistentmodelindex,
354 "QSet_QPersistentModelIndex"
355);
356impl_qset_element!(QString, qset_qstring, "QSet_QString");
357impl_qset_element!(QTime, qset_qtime, "QSet_QTime");
358impl_qset_element!(QUrl, qset_qurl, "QSet_QUrl");
359impl_qset_element!(QUuid, qset_quuid, "QSet_QUuid");
360impl_qset_element!(u8, qset_u8, "QSet_u8");
361impl_qset_element!(u16, qset_u16, "QSet_u16");
362impl_qset_element!(u32, qset_u32, "QSet_u32");
363impl_qset_element!(u64, qset_u64, "QSet_u64");
364
365#[cfg(test)]
366mod test {
367 use super::*;
368
369 #[cfg(feature = "serde")]
370 #[test]
371 fn qset_serde() {
372 let mut set = QSet::default();
373 set.insert(0);
374 set.insert(1);
375 set.insert(2);
376 assert_eq!(crate::serde_impl::roundtrip(&set), set)
377 }
378}