1#[cfg(feature = "qt_gui")]
7use crate::QColor;
8#[cfg(not(target_os = "emscripten"))]
9use crate::QDateTime;
10use crate::{
11 QByteArray, QDate, QLine, QLineF, QMargins, QMarginsF, QPersistentModelIndex, QPoint, QPointF,
12 QRect, QRectF, QSize, QSizeF, QString, QTime, QUrl, QUuid, QVariant,
13};
14use core::{marker::PhantomData, mem::MaybeUninit};
15use cxx::{type_id, ExternType};
16use std::fmt;
17
18#[repr(C)]
24pub struct QVector<T>
25where
26 T: QVectorElement,
27{
28 #[cfg(cxxqt_qt_version_major = "5")]
33 _space: MaybeUninit<usize>,
34 #[cfg(cxxqt_qt_version_major = "6")]
35 _space: MaybeUninit<[usize; 3]>,
36 _value: PhantomData<T>,
37}
38
39impl<T> Clone for QVector<T>
40where
41 T: QVectorElement,
42{
43 fn clone(&self) -> Self {
45 T::clone(self)
46 }
47}
48
49impl<T> Default for QVector<T>
50where
51 T: QVectorElement,
52{
53 fn default() -> Self {
55 T::default()
56 }
57}
58
59impl<T> Drop for QVector<T>
60where
61 T: QVectorElement,
62{
63 fn drop(&mut self) {
65 T::drop(self);
66 }
67}
68
69impl<T> PartialEq for QVector<T>
70where
71 T: QVectorElement + PartialEq,
72{
73 fn eq(&self, other: &Self) -> bool {
75 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b)
76 }
77}
78
79impl<T> Eq for QVector<T> where T: QVectorElement + Eq {}
80
81impl<T> fmt::Debug for QVector<T>
82where
83 T: QVectorElement + fmt::Debug,
84{
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 f.debug_list().entries(self.iter()).finish()
87 }
88}
89
90impl<T> QVector<T>
91where
92 T: QVectorElement,
93{
94 pub fn append_clone(&mut self, value: &T) {
99 T::append_clone(self, value);
100 }
101
102 pub fn clear(&mut self) {
106 T::clear(self);
107 }
108
109 pub fn contains(&self, value: &T) -> bool {
111 T::contains(self, value)
112 }
113
114 pub fn get(&self, index: isize) -> Option<&T> {
116 if index >= 0 && index < self.len() {
117 Some(unsafe { T::get_unchecked(self, index) })
118 } else {
119 None
120 }
121 }
122
123 pub fn index_of(&self, value: &T) -> isize {
125 T::index_of(self, value)
126 }
127
128 pub fn insert_clone(&mut self, pos: isize, value: &T) {
133 T::insert_clone(self, pos, value);
134 }
135
136 pub fn is_empty(&self) -> bool {
138 T::len(self) == 0
139 }
140
141 pub fn iter(&self) -> Iter<'_, T> {
144 Iter {
145 vector: self,
146 index: 0,
147 }
148 }
149
150 pub fn len(&self) -> isize {
152 T::len(self)
153 }
154
155 pub fn remove(&mut self, pos: isize) {
157 T::remove(self, pos);
158 }
159
160 pub fn reserve(&mut self, size: isize) {
166 T::reserve(self, size);
167 }
168
169 pub(crate) fn reserve_usize(&mut self, size: usize) {
171 if size != 0 {
172 T::reserve(self, isize::try_from(size).unwrap_or(isize::MAX));
173 }
174 }
175}
176
177impl<T> QVector<T>
178where
179 T: QVectorElement + ExternType<Kind = cxx::kind::Trivial>,
180{
181 pub fn append(&mut self, value: T) {
183 T::append(self, value);
184 }
185
186 pub fn insert(&mut self, pos: isize, value: T) {
188 T::insert(self, pos, value);
189 }
190}
191
192impl<T> From<&QVector<T>> for Vec<T>
193where
194 T: QVectorElement + Clone,
195{
196 fn from(qvec: &QVector<T>) -> Self {
199 qvec.iter().cloned().collect()
200 }
201}
202
203impl<T, S> From<S> for QVector<T>
204where
205 T: QVectorElement + Clone,
206 S: AsRef<[T]>,
207{
208 fn from(vec: S) -> Self {
212 vec.as_ref().iter().collect()
213 }
214}
215impl<'a, T> Extend<&'a T> for QVector<T>
216where
217 T: QVectorElement,
218{
219 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
220 let iter = iter.into_iter();
221 self.reserve_usize(iter.size_hint().0);
222 for element in iter {
223 self.append_clone(element);
224 }
225 }
226}
227
228impl<T> Extend<T> for QVector<T>
229where
230 T: QVectorElement + ExternType<Kind = cxx::kind::Trivial>,
231{
232 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
233 let iter = iter.into_iter();
234 self.reserve_usize(iter.size_hint().0);
235 for element in iter {
236 self.append(element);
237 }
238 }
239}
240
241impl<'a, T> FromIterator<&'a T> for QVector<T>
242where
243 T: QVectorElement,
244{
245 fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self {
246 let mut qlist = Self::default();
247 qlist.extend(iter);
248 qlist
249 }
250}
251
252impl<T> FromIterator<T> for QVector<T>
253where
254 T: QVectorElement + ExternType<Kind = cxx::kind::Trivial>,
255{
256 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
257 let mut qlist = Self::default();
258 qlist.extend(iter);
259 qlist
260 }
261}
262
263unsafe impl<T> ExternType for QVector<T>
264where
265 T: ExternType + QVectorElement,
266{
267 type Id = T::TypeId;
268 type Kind = cxx::kind::Trivial;
269}
270
271pub struct Iter<'a, T>
272where
273 T: QVectorElement,
274{
275 vector: &'a QVector<T>,
276 index: isize,
277}
278
279impl<'a, T> Iterator for Iter<'a, T>
280where
281 T: QVectorElement,
282{
283 type Item = &'a T;
284
285 fn next(&mut self) -> Option<Self::Item> {
286 if self.index < self.vector.len() {
287 let next = unsafe { T::get_unchecked(self.vector, self.index) };
288 self.index += 1;
289 Some(next)
290 } else {
291 None
292 }
293 }
294
295 fn size_hint(&self) -> (usize, Option<usize>) {
296 let len = self.len();
297 (len, Some(len))
298 }
299}
300
301impl<T> ExactSizeIterator for Iter<'_, T>
302where
303 T: QVectorElement,
304{
305 fn len(&self) -> usize {
306 (self.vector.len() - self.index) as usize
307 }
308}
309
310impl<'a, T> IntoIterator for &'a QVector<T>
311where
312 T: QVectorElement,
313{
314 type Item = &'a T;
315
316 type IntoIter = Iter<'a, T>;
317
318 fn into_iter(self) -> Self::IntoIter {
319 self.iter()
320 }
321}
322
323pub trait QVectorElement: Sized {
325 type TypeId;
326
327 fn append(vector: &mut QVector<Self>, value: Self)
328 where
329 Self: ExternType<Kind = cxx::kind::Trivial>;
330 fn append_clone(vector: &mut QVector<Self>, value: &Self);
331 fn clear(vector: &mut QVector<Self>);
332 fn clone(vector: &QVector<Self>) -> QVector<Self>;
333 fn contains(vector: &QVector<Self>, value: &Self) -> bool;
334 fn default() -> QVector<Self>;
335 fn drop(vector: &mut QVector<Self>);
336 unsafe fn get_unchecked(vector: &QVector<Self>, pos: isize) -> &Self;
341 fn index_of(vector: &QVector<Self>, value: &Self) -> isize;
342 fn insert(vector: &mut QVector<Self>, pos: isize, value: Self)
343 where
344 Self: ExternType<Kind = cxx::kind::Trivial>;
345 fn insert_clone(vector: &mut QVector<Self>, pos: isize, value: &Self);
346 fn len(vector: &QVector<Self>) -> isize;
347 fn remove(vector: &mut QVector<Self>, pos: isize);
348 fn reserve(vector: &mut QVector<Self>, size: isize);
349}
350
351macro_rules! impl_qvector_element {
352 ( $typeName:ty, $module:ident, $typeId:literal ) => {
353 mod $module;
354
355 impl QVectorElement for $typeName {
356 type TypeId = type_id!($typeId);
357
358 fn append(vector: &mut QVector<Self>, value: Self) {
359 $module::append(vector, &value);
360 }
361
362 fn append_clone(vector: &mut QVector<Self>, value: &Self) {
363 $module::append(vector, value);
364 }
365
366 fn clear(vector: &mut QVector<Self>) {
367 vector.cxx_clear()
368 }
369
370 fn clone(vector: &QVector<Self>) -> QVector<Self> {
371 $module::clone(vector)
372 }
373
374 fn contains(vector: &QVector<Self>, value: &Self) -> bool {
375 vector.cxx_contains(value)
376 }
377
378 fn default() -> QVector<Self> {
379 $module::default()
380 }
381
382 fn drop(vector: &mut QVector<Self>) {
383 $module::drop(vector);
384 }
385
386 unsafe fn get_unchecked(vector: &QVector<Self>, pos: isize) -> &Self {
387 $module::get_unchecked(vector, pos)
388 }
389
390 fn index_of(vector: &QVector<Self>, value: &Self) -> isize {
391 $module::index_of(vector, value)
392 }
393
394 fn insert(vector: &mut QVector<Self>, pos: isize, value: Self) {
395 $module::insert(vector, pos, &value);
396 }
397
398 fn insert_clone(vector: &mut QVector<Self>, pos: isize, value: &Self) {
399 $module::insert(vector, pos, value);
400 }
401
402 fn len(vector: &QVector<Self>) -> isize {
403 $module::len(vector)
404 }
405
406 fn remove(vector: &mut QVector<Self>, pos: isize) {
407 $module::remove(vector, pos);
408 }
409
410 fn reserve(vector: &mut QVector<Self>, size: isize) {
411 $module::reserve(vector, size);
412 }
413 }
414 };
415}
416
417impl_qvector_element!(bool, qvector_bool, "QVector_bool");
418impl_qvector_element!(f32, qvector_f32, "QVector_f32");
419impl_qvector_element!(f64, qvector_f64, "QVector_f64");
420impl_qvector_element!(i8, qvector_i8, "QVector_i8");
421impl_qvector_element!(i16, qvector_i16, "QVector_i16");
422impl_qvector_element!(i32, qvector_i32, "QVector_i32");
423impl_qvector_element!(i64, qvector_i64, "QVector_i64");
424impl_qvector_element!(QByteArray, qvector_qbytearray, "QVector_QByteArray");
425#[cfg(feature = "qt_gui")]
426impl_qvector_element!(QColor, qvector_qcolor, "QVector_QColor");
427impl_qvector_element!(QDate, qvector_qdate, "QVector_QDate");
428#[cfg(not(target_os = "emscripten"))]
429impl_qvector_element!(QDateTime, qvector_qdatetime, "QVector_QDateTime");
430impl_qvector_element!(QLine, qvector_qline, "QVector_QLine");
431impl_qvector_element!(QLineF, qvector_qlinef, "QVector_QLineF");
432impl_qvector_element!(QMargins, qvector_qmargins, "QVector_QMargins");
433impl_qvector_element!(QMarginsF, qvector_qmarginsf, "QVector_QMarginsF");
434impl_qvector_element!(
435 QPersistentModelIndex,
436 qvector_qpersistentmodelindex,
437 "QVector_QPersistentModelIndex"
438);
439impl_qvector_element!(QPoint, qvector_qpoint, "QVector_QPoint");
440impl_qvector_element!(QPointF, qvector_qpointf, "QVector_QPointF");
441impl_qvector_element!(QRect, qvector_qrect, "QVector_QRect");
442impl_qvector_element!(QRectF, qvector_qrectf, "QVector_QRectF");
443impl_qvector_element!(QSize, qvector_qsize, "QVector_QSize");
444impl_qvector_element!(QSizeF, qvector_qsizef, "QVector_QSizeF");
445impl_qvector_element!(QString, qvector_qstring, "QVector_QString");
446impl_qvector_element!(QTime, qvector_qtime, "QVector_QTime");
447impl_qvector_element!(QUrl, qvector_qurl, "QVector_QUrl");
448impl_qvector_element!(QUuid, qvector_quuid, "QVector_QUuid");
449impl_qvector_element!(QVariant, qvector_qvariant, "QVector_QVariant");
450impl_qvector_element!(u8, qvector_u8, "QVector_u8");
451impl_qvector_element!(u16, qvector_u16, "QVector_u16");
452impl_qvector_element!(u32, qvector_u32, "QVector_u32");
453impl_qvector_element!(u64, qvector_u64, "QVector_u64");
454
455#[cfg(test)]
456mod test {
457 use super::*;
458
459 #[test]
460 fn qvec_from_array_to_vec() {
461 let array = [0, 1, 2];
462 let qvec = QVector::<u8>::from(array);
463 assert_eq!(Vec::from(&qvec), array);
464 }
465
466 #[cfg(feature = "serde")]
467 #[test]
468 fn qvec_serde() {
469 let qvec = QVector::<u8>::from([0, 1, 2]);
470 assert_eq!(crate::serde_impl::roundtrip(&qvec), qvec);
471 }
472}