1#[cfg(not(target_os = "emscripten"))]
6use crate::QDateTime;
7use crate::{QByteArray, QDate, QPersistentModelIndex, QString, QTime, QUrl};
8use core::{marker::PhantomData, mem::MaybeUninit};
9use cxx::{type_id, ExternType};
10
11#[repr(C)]
17pub struct QSet<T>
18where
19 T: QSetElement,
20{
21 _space: MaybeUninit<usize>,
22 _value: PhantomData<T>,
23}
24
25impl<T> Clone for QSet<T>
26where
27 T: QSetElement,
28{
29 fn clone(&self) -> Self {
31 T::clone(self)
32 }
33}
34
35impl<T> Default for QSet<T>
36where
37 T: QSetElement,
38{
39 fn default() -> Self {
41 T::default()
42 }
43}
44
45impl<T> Drop for QSet<T>
46where
47 T: QSetElement,
48{
49 fn drop(&mut self) {
51 T::drop(self);
52 }
53}
54
55impl<T> PartialEq for QSet<T>
56where
57 T: QSetElement + PartialEq,
58{
59 fn eq(&self, other: &Self) -> bool {
61 self.len() == other.len() && self.iter().all(|x| other.contains(x))
62 }
63}
64
65impl<T> Eq for QSet<T> where T: QSetElement + PartialEq {}
66
67impl<T> QSet<T>
68where
69 T: QSetElement,
70{
71 pub fn clear(&mut self) {
73 T::clear(self);
74 }
75
76 pub fn contains(&self, value: &T) -> bool {
78 T::contains(self, value)
79 }
80
81 pub fn insert_clone(&mut self, value: &T) {
87 T::insert_clone(self, value);
88 }
89
90 pub fn is_empty(&self) -> bool {
92 T::len(self) == 0
93 }
94
95 pub fn iter(&self) -> Iter<'_, T> {
98 Iter {
99 set: self,
100 index: 0,
101 }
102 }
103
104 pub fn len(&self) -> isize {
106 T::len(self)
107 }
108
109 pub fn remove(&mut self, value: &T) -> bool {
112 T::remove(self, value)
113 }
114}
115
116impl<T> QSet<T>
117where
118 T: QSetElement + ExternType<Kind = cxx::kind::Trivial>,
119{
120 pub fn insert(&mut self, value: T) {
123 T::insert(self, value);
124 }
125}
126
127unsafe impl<T> ExternType for QSet<T>
128where
129 T: ExternType + QSetElement,
130{
131 type Id = T::TypeId;
132 type Kind = cxx::kind::Trivial;
133}
134
135pub struct Iter<'a, T>
136where
137 T: QSetElement,
138{
139 set: &'a QSet<T>,
140 index: isize,
141}
142
143impl<'a, T> Iterator for Iter<'a, T>
144where
145 T: QSetElement,
146{
147 type Item = &'a T;
148
149 fn next(&mut self) -> Option<Self::Item> {
150 if self.index < self.set.len() {
151 let next = unsafe { T::get_unchecked(self.set, self.index) };
152 self.index += 1;
153 Some(next)
154 } else {
155 None
156 }
157 }
158
159 fn size_hint(&self) -> (usize, Option<usize>) {
160 let len = self.len();
161 (len, Some(len))
162 }
163}
164
165impl<T> ExactSizeIterator for Iter<'_, T>
166where
167 T: QSetElement,
168{
169 fn len(&self) -> usize {
170 (self.set.len() - self.index) as usize
171 }
172}
173
174pub trait QSetElement: Sized {
176 type TypeId;
177
178 fn clear(set: &mut QSet<Self>);
179 fn clone(set: &QSet<Self>) -> QSet<Self>;
180 fn contains(set: &QSet<Self>, value: &Self) -> bool;
181 fn default() -> QSet<Self>;
182 fn drop(set: &mut QSet<Self>);
183 unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self;
188 fn insert(set: &mut QSet<Self>, value: Self)
189 where
190 Self: ExternType<Kind = cxx::kind::Trivial>;
191 fn insert_clone(set: &mut QSet<Self>, value: &Self);
192 fn len(set: &QSet<Self>) -> isize;
193 fn remove(set: &mut QSet<Self>, value: &Self) -> bool;
194}
195
196macro_rules! impl_qset_element {
197 ( $typeName:ty, $module:ident, $typeId:literal ) => {
198 mod $module;
199
200 impl QSetElement for $typeName {
201 type TypeId = type_id!($typeId);
202
203 fn clear(set: &mut QSet<Self>) {
204 set.cxx_clear()
205 }
206
207 fn clone(set: &QSet<Self>) -> QSet<Self> {
208 $module::clone(set)
209 }
210
211 fn contains(set: &QSet<Self>, value: &Self) -> bool {
212 set.cxx_contains(value)
213 }
214
215 fn default() -> QSet<Self> {
216 $module::default()
217 }
218
219 fn drop(set: &mut QSet<Self>) {
220 $module::drop(set);
221 }
222
223 unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self {
224 $module::get_unchecked(set, pos)
225 }
226
227 fn insert(set: &mut QSet<Self>, value: Self) {
228 $module::insert(set, &value);
229 }
230
231 fn insert_clone(set: &mut QSet<Self>, value: &Self) {
232 $module::insert(set, value);
233 }
234
235 fn len(set: &QSet<Self>) -> isize {
236 $module::len(set)
237 }
238
239 fn remove(set: &mut QSet<Self>, value: &Self) -> bool {
240 set.cxx_remove(value)
241 }
242 }
243 };
244}
245
246impl_qset_element!(bool, qset_bool, "QSet_bool");
247impl_qset_element!(f32, qset_f32, "QSet_f32");
248impl_qset_element!(f64, qset_f64, "QSet_f64");
249impl_qset_element!(i8, qset_i8, "QSet_i8");
250impl_qset_element!(i16, qset_i16, "QSet_i16");
251impl_qset_element!(i32, qset_i32, "QSet_i32");
252impl_qset_element!(i64, qset_i64, "QSet_i64");
253impl_qset_element!(QByteArray, qset_qbytearray, "QSet_QByteArray");
254impl_qset_element!(QDate, qset_qdate, "QSet_QDate");
255#[cfg(not(target_os = "emscripten"))]
256impl_qset_element!(QDateTime, qset_qdatetime, "QSet_QDateTime");
257impl_qset_element!(
258 QPersistentModelIndex,
259 qset_qpersistentmodelindex,
260 "QSet_QPersistentModelIndex"
261);
262impl_qset_element!(QString, qset_qstring, "QSet_QString");
263impl_qset_element!(QTime, qset_qtime, "QSet_QTime");
264impl_qset_element!(QUrl, qset_qurl, "QSet_QUrl");
265impl_qset_element!(u8, qset_u8, "QSet_u8");
266impl_qset_element!(u16, qset_u16, "QSet_u16");
267impl_qset_element!(u32, qset_u32, "QSet_u32");
268impl_qset_element!(u64, qset_u64, "QSet_u64");