1use core::{marker::PhantomData, mem::MaybeUninit};
6use cxx::{type_id, ExternType};
7
8#[repr(C)]
12pub struct QMap<T>
13where
14 T: QMapPair,
15{
16 _space: MaybeUninit<usize>,
17 _value: PhantomData<T>,
18}
19
20impl<T> Clone for QMap<T>
21where
22 T: QMapPair,
23{
24 fn clone(&self) -> Self {
26 T::clone(self)
27 }
28}
29
30impl<T> Default for QMap<T>
31where
32 T: QMapPair,
33{
34 fn default() -> Self {
36 T::default()
37 }
38}
39
40impl<T> Drop for QMap<T>
41where
42 T: QMapPair,
43{
44 fn drop(&mut self) {
46 T::drop(self)
47 }
48}
49
50impl<T> PartialEq for QMap<T>
51where
52 T: QMapPair,
53 T::Value: PartialEq,
54{
55 fn eq(&self, other: &Self) -> bool {
57 self.len() == other.len() && self.iter().all(|(k, v)| other.get(k).as_ref() == Some(v))
58 }
59}
60
61impl<T> Eq for QMap<T>
62where
63 T: QMapPair,
64 T::Value: Eq,
65{
66}
67
68impl<T> QMap<T>
69where
70 T: QMapPair,
71{
72 pub fn clear(&mut self) {
74 T::clear(self)
75 }
76
77 pub fn contains(&self, key: &T::Key) -> bool {
79 T::contains(self, key)
80 }
81
82 pub fn get(&self, key: &T::Key) -> Option<T::Value> {
84 if self.contains(key) {
85 Some(T::get_or_default(self, key))
86 } else {
87 None
88 }
89 }
90
91 pub fn get_or_default(&self, key: &T::Key) -> T::Value {
93 T::get_or_default(self, key)
94 }
95
96 pub fn insert_clone(&mut self, key: &T::Key, value: &T::Value) {
101 T::insert_clone(self, key, value)
102 }
103
104 pub fn is_empty(&self) -> bool {
106 T::len(self) == 0
107 }
108
109 pub fn iter(&self) -> Iter<'_, T> {
112 Iter {
113 map: self,
114 index: 0,
115 }
116 }
117
118 pub fn len(&self) -> isize {
120 T::len(self)
121 }
122
123 pub fn remove(&mut self, key: &T::Key) -> bool {
125 T::remove(self, key)
126 }
127}
128
129impl<T> QMap<T>
130where
131 T: QMapPair,
132 T::Key: ExternType<Kind = cxx::kind::Trivial>,
133 T::Value: ExternType<Kind = cxx::kind::Trivial>,
134{
135 pub fn insert(&mut self, key: T::Key, value: T::Value) {
137 T::insert(self, key, value)
138 }
139}
140
141unsafe impl<T> ExternType for QMap<T>
142where
143 T: QMapPair,
144{
145 type Id = T::TypeId;
146 type Kind = cxx::kind::Trivial;
147}
148
149pub struct Iter<'a, T>
150where
151 T: QMapPair,
152{
153 map: &'a QMap<T>,
154 index: isize,
155}
156
157impl<'a, T> Iterator for Iter<'a, T>
158where
159 T: QMapPair,
160{
161 type Item = (&'a T::Key, &'a T::Value);
162
163 fn next(&mut self) -> Option<Self::Item> {
164 if self.index < self.map.len() {
165 let next = unsafe {
166 (
167 T::get_unchecked_key(self.map, self.index),
168 T::get_unchecked_value(self.map, self.index),
169 )
170 };
171 self.index += 1;
172 Some(next)
173 } else {
174 None
175 }
176 }
177
178 fn size_hint(&self) -> (usize, Option<usize>) {
179 let len = self.len();
180 (len, Some(len))
181 }
182}
183
184impl<T> ExactSizeIterator for Iter<'_, T>
185where
186 T: QMapPair,
187{
188 fn len(&self) -> usize {
189 (self.map.len() - self.index) as usize
190 }
191}
192
193pub trait QMapPair: Sized {
195 type Key;
196 type Value;
197 type TypeId;
198
199 fn clear(map: &mut QMap<Self>);
200 fn clone(map: &QMap<Self>) -> QMap<Self>;
201 fn contains(map: &QMap<Self>, key: &Self::Key) -> bool;
202 fn default() -> QMap<Self>;
203 fn drop(map: &mut QMap<Self>);
204 fn get_or_default(map: &QMap<Self>, key: &Self::Key) -> Self::Value;
205 unsafe fn get_unchecked_key(map: &QMap<Self>, pos: isize) -> &Self::Key;
210 unsafe fn get_unchecked_value(map: &QMap<Self>, pos: isize) -> &Self::Value;
215 fn insert(map: &mut QMap<Self>, key: Self::Key, value: Self::Value)
216 where
217 Self::Key: ExternType<Kind = cxx::kind::Trivial>,
218 Self::Value: ExternType<Kind = cxx::kind::Trivial>;
219 fn insert_clone(map: &mut QMap<Self>, key: &Self::Key, value: &Self::Value);
220 fn len(map: &QMap<Self>) -> isize;
221 fn remove(map: &mut QMap<Self>, key: &Self::Key) -> bool;
222}
223
224macro_rules! impl_qmap_pair {
225 ( $keyTypeName:ty, $valueTypeName:ty, $module:ident, $pairTypeName:ident, $typeId:literal ) => {
226 mod $module;
227 pub use $module::$pairTypeName;
228
229 impl QMapPair for $module::$pairTypeName {
230 type Key = $keyTypeName;
231 type Value = $valueTypeName;
232 type TypeId = type_id!($typeId);
233
234 fn clear(map: &mut QMap<Self>) {
235 map.cxx_clear();
236 }
237
238 fn clone(map: &QMap<Self>) -> QMap<Self> {
239 $module::clone(map)
240 }
241
242 fn contains(map: &QMap<Self>, key: &$keyTypeName) -> bool {
243 map.cxx_contains(key)
244 }
245
246 fn default() -> QMap<Self> {
247 $module::default()
248 }
249
250 fn drop(map: &mut QMap<Self>) {
251 $module::drop(map);
252 }
253
254 fn get_or_default(map: &QMap<Self>, key: &$keyTypeName) -> $valueTypeName {
255 $module::get_or_default(map, key)
256 }
257
258 unsafe fn get_unchecked_key(map: &QMap<Self>, pos: isize) -> &$keyTypeName {
259 $module::get_unchecked_key(map, pos)
260 }
261
262 unsafe fn get_unchecked_value(map: &QMap<Self>, pos: isize) -> &$valueTypeName {
263 $module::get_unchecked_value(map, pos)
264 }
265
266 fn insert(map: &mut QMap<Self>, key: $keyTypeName, value: $valueTypeName) {
267 $module::insert(map, &key, &value);
268 }
269
270 fn insert_clone(map: &mut QMap<Self>, key: &$keyTypeName, value: &$valueTypeName) {
271 $module::insert(map, key, value);
272 }
273
274 fn len(map: &QMap<Self>) -> isize {
275 $module::len(map)
276 }
277
278 fn remove(map: &mut QMap<Self>, key: &$keyTypeName) -> bool {
279 $module::remove(map, key)
280 }
281 }
282 };
283}
284
285impl_qmap_pair!(
291 crate::QString,
292 crate::QVariant,
293 qmap_qstring_qvariant,
294 QMapPair_QString_QVariant,
295 "QMap_QString_QVariant"
296);