diff --git a/crates/cxx-qt-lib/src/core/qstringlist.cpp b/crates/cxx-qt-lib/src/core/qstringlist.cpp index a5ea48a60..12382c657 100644 --- a/crates/cxx-qt-lib/src/core/qstringlist.cpp +++ b/crates/cxx-qt-lib/src/core/qstringlist.cpp @@ -36,18 +36,6 @@ static_assert(QTypeInfo::isRelocatable); namespace rust { namespace cxxqtlib1 { -const QList& -qstringlistAsQListQStringRef(const QStringList& list) -{ - return static_cast&>(list); -} - -QList& -qstringlistAsQListQStringRef(QStringList& list) -{ - return static_cast&>(list); -} - QStringList qstringlistFromQListQString(const QList& list) { diff --git a/crates/cxx-qt-lib/src/core/qstringlist.rs b/crates/cxx-qt-lib/src/core/qstringlist.rs index 22d9d3886..1e8fd47e1 100644 --- a/crates/cxx-qt-lib/src/core/qstringlist.rs +++ b/crates/cxx-qt-lib/src/core/qstringlist.rs @@ -2,9 +2,11 @@ // SPDX-FileContributor: Andrew Hayzen // // SPDX-License-Identifier: MIT OR Apache-2.0 +use crate::core::qstringlist::ffi::{downcast_qlist_qstring, upcast_qstringlist, QList_QString}; use crate::{QList, QString}; use core::mem::MaybeUninit; use cxx::{type_id, ExternType}; +use cxx_qt::Upcast; use std::ops::{Deref, DerefMut}; #[cxx::bridge] @@ -25,6 +27,20 @@ mod ffi { include!("cxx-qt-lib/qstringlist.h"); type QStringList = super::QStringList; + include!("cxx-qt/casting.h"); + + #[doc(hidden)] + #[rust_name = "upcast_qstringlist"] + #[cxx_name = "upcastPtr"] + #[namespace = "rust::cxxqt1"] + unsafe fn upcast(thiz: *const QStringList) -> *const QList_QString; + + #[doc(hidden)] + #[rust_name = "downcast_qlist_qstring"] + #[cxx_name = "downcastPtr"] + #[namespace = "rust::cxxqt1"] + unsafe fn downcast(base: *const QList_QString) -> *const QStringList; + /// Returns true if the list contains the string str; otherwise returns false. fn contains(self: &QStringList, str: &QString, cs: CaseSensitivity) -> bool; @@ -80,11 +96,6 @@ mod ffi { #[namespace = "rust::cxxqtlib1"] unsafe extern "C++" { - #[doc(hidden)] - #[rust_name = "qstringlist_as_qlist_qstring_ref"] - fn qstringlistAsQListQStringRef(list: &QStringList) -> &QList_QString; - #[rust_name = "qstringlist_as_qlist_qstring_ref_mut"] - fn qstringlistAsQListQStringRef(list: &mut QStringList) -> &mut QList_QString; #[doc(hidden)] #[rust_name = "qstringlist_from_qlist_qstring"] fn qstringlistFromQListQString(list: &QList_QString) -> QStringList; @@ -184,13 +195,23 @@ impl Deref for QStringList { type Target = QList; fn deref(&self) -> &Self::Target { - ffi::qstringlist_as_qlist_qstring_ref(self) + self.upcast() } } impl DerefMut for QStringList { fn deref_mut(&mut self) -> &mut Self::Target { - ffi::qstringlist_as_qlist_qstring_ref_mut(self) + self.upcast_mut() + } +} + +impl Upcast for QStringList { + unsafe fn upcast_ptr(this: *const Self) -> *const QList_QString { + upcast_qstringlist(this) + } + + unsafe fn from_base_ptr(base: *const QList_QString) -> *const Self { + downcast_qlist_qstring(base) } } diff --git a/crates/cxx-qt-lib/src/gui/qguiapplication.rs b/crates/cxx-qt-lib/src/gui/qguiapplication.rs index 62aabc406..f23abe12f 100644 --- a/crates/cxx-qt-lib/src/gui/qguiapplication.rs +++ b/crates/cxx-qt-lib/src/gui/qguiapplication.rs @@ -6,6 +6,7 @@ use crate::{QByteArray, QFont, QString, QStringList, QVector}; use core::pin::Pin; +use cxx_qt::Upcast; #[cxx::bridge] mod ffi { @@ -23,6 +24,23 @@ mod ffi { include!("cxx-qt-lib/qguiapplication.h"); type QGuiApplication; + + include!("cxx-qt-lib/qcoreapplication.h"); + type QCoreApplication; + + include!("cxx-qt/casting.h"); + + #[doc(hidden)] + #[rust_name = "upcast_qguiapplication"] + #[cxx_name = "upcastPtr"] + #[namespace = "rust::cxxqt1"] + unsafe fn upcast(thiz: *const QGuiApplication) -> *const QCoreApplication; + + #[doc(hidden)] + #[rust_name = "downcast_qcoreapplication"] + #[cxx_name = "downcastPtr"] + #[namespace = "rust::cxxqt1"] + unsafe fn downcast(base: *const QCoreApplication) -> *const QGuiApplication; } #[namespace = "rust::cxxqtlib1"] @@ -98,7 +116,19 @@ mod ffi { impl UniquePtr {} } -pub use ffi::QGuiApplication; +pub use ffi::{ + downcast_qcoreapplication, upcast_qguiapplication, QCoreApplication, QGuiApplication, +}; + +impl Upcast for QGuiApplication { + unsafe fn upcast_ptr(this: *const Self) -> *const QCoreApplication { + upcast_qguiapplication(this) + } + + unsafe fn from_base_ptr(base: *const QCoreApplication) -> *const Self { + downcast_qcoreapplication(base) + } +} impl QGuiApplication { /// Prepends path to the beginning of the library path list, diff --git a/crates/cxx-qt/src/lib.rs b/crates/cxx-qt/src/lib.rs index cfde22549..8bb21755d 100644 --- a/crates/cxx-qt/src/lib.rs +++ b/crates/cxx-qt/src/lib.rs @@ -177,6 +177,31 @@ pub trait Downcast: Sized { } } } + + /// try Downcast mutably to a subclass of this, given that the subclass upcasts to this type + fn downcast_mut>(&mut self) -> Option<&mut Sub> { + unsafe { + let ptr = Sub::from_base_ptr(self as *const Self) as *mut Sub; + if ptr.is_null() { + None + } else { + Some(&mut *ptr) + } + } + } + + /// try Downcast a pin to a pinned subclass of this, given that the subclass upcasts to this type + fn downcast_pin>(self: Pin<&mut Self>) -> Option> { + let this = self.deref() as *const Self; + unsafe { + let ptr = Sub::from_base_ptr(this) as *mut Sub; + if ptr.is_null() { + None + } else { + Some(Pin::new_unchecked(&mut *ptr)) + } + } + } } impl Downcast for T {}