diff --git a/CHANGELOG.md b/CHANGELOG.md index ddf3c0dde..66d070db7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Support for further types: `QLine`, `QLineF`, `QImage`, `QPainter`, `QFont`, `QPen`, `QPolygon`, `QPolygonF`, `QRegion`, `QAnyStringView` +- Support for further types: `QLine`, `QLineF`, `QImage`, `QPainter`, `QFont`, `QPen`, `QPolygon`, `QPolygonF`, `QRegion`, `QAnyStringView`, `qreal`, `QInt64`, `QIntPtr`, `QUInt64`, `QUIntPtr` - `internal_pointer_mut()` function on `QModelIndex` - `c_void` in CXX-Qt-lib for easy access to `void *` - `CxxQtThread` is now marked as `Sync` so that it can be used by reference diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index b6006a02c..f3fde01a0 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -147,6 +147,7 @@ fn main() { "core/qstringlist", "core/qt", "core/qtime", + "core/qtypes", "core/qurl", "core/qvariant/mod", "core/qvariant/qvariant_bool", @@ -271,6 +272,7 @@ fn main() { "core/qstring", "core/qstringlist", "core/qtime", + "core/qtypes", "core/qurl", "core/qvariant/qvariant", "core/qvector/qvector", diff --git a/crates/cxx-qt-lib/include/core/qtypes.h b/crates/cxx-qt-lib/include/core/qtypes.h new file mode 100644 index 000000000..16239f4e6 --- /dev/null +++ b/crates/cxx-qt-lib/include/core/qtypes.h @@ -0,0 +1,9 @@ +// clang-format off +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#pragma once + +#include diff --git a/crates/cxx-qt-lib/src/core/mod.rs b/crates/cxx-qt-lib/src/core/mod.rs index a2e9bfa33..27406d676 100644 --- a/crates/cxx-qt-lib/src/core/mod.rs +++ b/crates/cxx-qt-lib/src/core/mod.rs @@ -83,6 +83,9 @@ pub use qt::{ mod qtime; pub use qtime::QTime; +mod qtypes; +pub use qtypes::{qreal, QInt64, QIntPtr, QSizeType, QUInt64, QUIntPtr}; + #[cfg(not(target_os = "emscripten"))] mod qtimezone; #[cfg(not(target_os = "emscripten"))] diff --git a/crates/cxx-qt-lib/src/core/qtypes.cpp b/crates/cxx-qt-lib/src/core/qtypes.cpp new file mode 100644 index 000000000..b37559271 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qtypes.cpp @@ -0,0 +1,17 @@ +// clang-format off +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#include "cxx-qt-lib/qtypes.h" + +#include "cxx-qt-lib/assertion_utils.h" + +assert_alignment_and_size(qint64, { ::std::int64_t a0; }); +assert_alignment_and_size(qintptr, { ::std::intptr_t a0; }); +assert_alignment_and_size(quint64, { ::std::uint64_t a0; }); +assert_alignment_and_size(quintptr, { ::std::uintptr_t a0; }); +assert_alignment_and_size(qsizetype, { ::std::size_t a0; }); +// We only support qreal being a double +assert_alignment_and_size(qreal, { double a0; }); diff --git a/crates/cxx-qt-lib/src/core/qtypes.rs b/crates/cxx-qt-lib/src/core/qtypes.rs new file mode 100644 index 000000000..f74214e49 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qtypes.rs @@ -0,0 +1,253 @@ +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use cxx::{type_id, ExternType}; +use std::ops::{Deref, DerefMut}; + +#[cxx::bridge] +mod ffi { + unsafe extern "C++" { + include!("cxx-qt-lib/qtypes.h"); + } +} + +/// Typedef for long long int. This type is guaranteed to be 64-bit on all platforms supported by Qt. +#[repr(transparent)] +#[derive(Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct QInt64(i64); + +impl Deref for QInt64 { + type Target = i64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for QInt64 { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for QInt64 { + fn from(value: i64) -> Self { + Self(value) + } +} + +impl From for i64 { + fn from(value: QInt64) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QInt64 { + type Id = type_id!("qint64"); + type Kind = cxx::kind::Trivial; +} + +/// Integral type for representing pointers in a signed integer (useful for hashing, etc.). +#[repr(transparent)] +#[derive(Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct QIntPtr(isize); + +impl Deref for QIntPtr { + type Target = isize; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for QIntPtr { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for QIntPtr { + fn from(value: isize) -> Self { + QIntPtr(value) + } +} + +impl From for isize { + fn from(value: QIntPtr) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QIntPtr { + type Id = type_id!("qintptr"); + type Kind = cxx::kind::Trivial; +} + +/// Typedef for double +/// +/// Note that configuring Qt with -qreal float is not supported +#[repr(transparent)] +#[derive(Default, Debug, PartialEq, PartialOrd)] +#[allow(non_camel_case_types)] +pub struct qreal(f64); + +impl Deref for qreal { + type Target = f64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for qreal { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for qreal { + fn from(value: f64) -> Self { + qreal(value) + } +} + +impl From for f64 { + fn from(value: qreal) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for qreal { + type Id = type_id!("qreal"); + type Kind = cxx::kind::Trivial; +} + +/// Typedef for unsigned long long int. This type is guaranteed to be 64-bit on all platforms supported by Qt. +#[repr(transparent)] +#[derive(Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct QUInt64(u64); + +impl Deref for QUInt64 { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for QUInt64 { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for QUInt64 { + fn from(value: u64) -> Self { + QUInt64(value) + } +} + +impl From for u64 { + fn from(value: QUInt64) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QUInt64 { + type Id = type_id!("quint64"); + type Kind = cxx::kind::Trivial; +} + +/// Integral type for representing pointers in an unsigned integer (useful for hashing, etc.). +#[repr(transparent)] +#[derive(Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct QUIntPtr(usize); + +impl Deref for QUIntPtr { + type Target = usize; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for QUIntPtr { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for QUIntPtr { + fn from(value: usize) -> Self { + QUIntPtr(value) + } +} + +impl From for usize { + fn from(value: QUIntPtr) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QUIntPtr { + type Id = type_id!("quintptr"); + type Kind = cxx::kind::Trivial; +} + +/// Integral type providing Posix' ssize_t for all platforms. +/// +/// This type is guaranteed to be the same size as a size_t on all platforms supported by Qt. +#[derive(Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[repr(transparent)] +pub struct QSizeType(isize); + +impl Deref for QSizeType { + type Target = isize; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for QSizeType { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for QSizeType { + fn from(value: isize) -> Self { + QSizeType(value) + } +} + +impl From for isize { + fn from(value: QSizeType) -> Self { + value.0 + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QSizeType { + type Id = type_id!("qsizetype"); + type Kind = cxx::kind::Trivial; +}