#[cfg(not(target_os = "emscripten"))]
use crate::QDateTime;
use crate::{QByteArray, QDate, QPersistentModelIndex, QString, QTime, QUrl};
use core::{marker::PhantomData, mem::MaybeUninit};
use cxx::{type_id, ExternType};
#[repr(C)]
pub struct QSet<T>
where
T: QSetElement,
{
_space: MaybeUninit<usize>,
_value: PhantomData<T>,
}
impl<T> Clone for QSet<T>
where
T: QSetElement,
{
fn clone(&self) -> Self {
T::clone(self)
}
}
impl<T> Default for QSet<T>
where
T: QSetElement,
{
fn default() -> Self {
T::default()
}
}
impl<T> Drop for QSet<T>
where
T: QSetElement,
{
fn drop(&mut self) {
T::drop(self);
}
}
impl<T> PartialEq for QSet<T>
where
T: QSetElement + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.len() == other.len() && self.iter().all(|x| other.contains(x))
}
}
impl<T> Eq for QSet<T> where T: QSetElement + PartialEq {}
impl<T> QSet<T>
where
T: QSetElement,
{
pub fn clear(&mut self) {
T::clear(self);
}
pub fn contains(&self, value: &T) -> bool {
T::contains(self, value)
}
pub fn insert_clone(&mut self, value: &T) {
T::insert_clone(self, value);
}
pub fn is_empty(&self) -> bool {
T::len(self) == 0
}
pub fn iter(&self) -> Iter<T> {
Iter {
set: self,
index: 0,
}
}
pub fn len(&self) -> isize {
T::len(self)
}
pub fn remove(&mut self, value: &T) -> bool {
T::remove(self, value)
}
}
impl<T> QSet<T>
where
T: QSetElement + ExternType<Kind = cxx::kind::Trivial>,
{
pub fn insert(&mut self, value: T) {
T::insert(self, value);
}
}
unsafe impl<T> ExternType for QSet<T>
where
T: ExternType + QSetElement,
{
type Id = T::TypeId;
type Kind = cxx::kind::Trivial;
}
pub struct Iter<'a, T>
where
T: QSetElement,
{
set: &'a QSet<T>,
index: isize,
}
impl<'a, T> Iterator for Iter<'a, T>
where
T: QSetElement,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.set.len() {
let next = unsafe { T::get_unchecked(self.set, self.index) };
self.index += 1;
Some(next)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<'a, T> ExactSizeIterator for Iter<'a, T>
where
T: QSetElement,
{
fn len(&self) -> usize {
(self.set.len() - self.index) as usize
}
}
pub trait QSetElement: Sized {
type TypeId;
fn clear(set: &mut QSet<Self>);
fn clone(set: &QSet<Self>) -> QSet<Self>;
fn contains(set: &QSet<Self>, value: &Self) -> bool;
fn default() -> QSet<Self>;
fn drop(set: &mut QSet<Self>);
unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self;
fn insert(set: &mut QSet<Self>, value: Self)
where
Self: ExternType<Kind = cxx::kind::Trivial>;
fn insert_clone(set: &mut QSet<Self>, value: &Self);
fn len(set: &QSet<Self>) -> isize;
fn remove(set: &mut QSet<Self>, value: &Self) -> bool;
}
macro_rules! impl_qset_element {
( $typeName:ty, $module:ident, $typeId:literal ) => {
mod $module;
impl QSetElement for $typeName {
type TypeId = type_id!($typeId);
fn clear(set: &mut QSet<Self>) {
set.cxx_clear()
}
fn clone(set: &QSet<Self>) -> QSet<Self> {
$module::clone(set)
}
fn contains(set: &QSet<Self>, value: &Self) -> bool {
set.cxx_contains(value)
}
fn default() -> QSet<Self> {
$module::default()
}
fn drop(set: &mut QSet<Self>) {
$module::drop(set);
}
unsafe fn get_unchecked(set: &QSet<Self>, pos: isize) -> &Self {
$module::get_unchecked(set, pos)
}
fn insert(set: &mut QSet<Self>, value: Self) {
$module::insert(set, &value);
}
fn insert_clone(set: &mut QSet<Self>, value: &Self) {
$module::insert(set, value);
}
fn len(set: &QSet<Self>) -> isize {
$module::len(set)
}
fn remove(set: &mut QSet<Self>, value: &Self) -> bool {
set.cxx_remove(value)
}
}
};
}
impl_qset_element!(bool, qset_bool, "QSet_bool");
impl_qset_element!(f32, qset_f32, "QSet_f32");
impl_qset_element!(f64, qset_f64, "QSet_f64");
impl_qset_element!(i8, qset_i8, "QSet_i8");
impl_qset_element!(i16, qset_i16, "QSet_i16");
impl_qset_element!(i32, qset_i32, "QSet_i32");
impl_qset_element!(i64, qset_i64, "QSet_i64");
impl_qset_element!(QByteArray, qset_qbytearray, "QSet_QByteArray");
impl_qset_element!(QDate, qset_qdate, "QSet_QDate");
#[cfg(not(target_os = "emscripten"))]
impl_qset_element!(QDateTime, qset_qdatetime, "QSet_QDateTime");
impl_qset_element!(
QPersistentModelIndex,
qset_qpersistentmodelindex,
"QSet_QPersistentModelIndex"
);
impl_qset_element!(QString, qset_qstring, "QSet_QString");
impl_qset_element!(QTime, qset_qtime, "QSet_QTime");
impl_qset_element!(QUrl, qset_qurl, "QSet_QUrl");
impl_qset_element!(u8, qset_u8, "QSet_u8");
impl_qset_element!(u16, qset_u16, "QSet_u16");
impl_qset_element!(u32, qset_u32, "QSet_u32");
impl_qset_element!(u64, qset_u64, "QSet_u64");