Skip to content

Commit

Permalink
qtypes: add support for Qt alias types that don't match
Browse files Browse the repository at this point in the history
Some times don't match the Rust types so add these missing types.

Closes KDAB#882
  • Loading branch information
ahayzen-kdab committed Oct 11, 2024
1 parent e6ee353 commit 18d370d
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ fn main() {
"core/qstringlist",
"core/qt",
"core/qtime",
"core/qtypes",
"core/qurl",
"core/qvariant/mod",
"core/qvariant/qvariant_bool",
Expand Down Expand Up @@ -271,6 +272,7 @@ fn main() {
"core/qstring",
"core/qstringlist",
"core/qtime",
"core/qtypes",
"core/qurl",
"core/qvariant/qvariant",
"core/qvector/qvector",
Expand Down
9 changes: 9 additions & 0 deletions crates/cxx-qt-lib/include/core/qtypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// clang-format off
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
#pragma once

#include <QtCore/Qt>
3 changes: 3 additions & 0 deletions crates/cxx-qt-lib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down
17 changes: 17 additions & 0 deletions crates/cxx-qt-lib/src/core/qtypes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// clang-format off
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// 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; });
253 changes: 253 additions & 0 deletions crates/cxx-qt-lib/src/core/qtypes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// 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<i64> for QInt64 {
fn from(value: i64) -> Self {
Self(value)
}
}

impl From<QInt64> 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<isize> for QIntPtr {
fn from(value: isize) -> Self {
QIntPtr(value)
}
}

impl From<QIntPtr> 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<f64> for qreal {
fn from(value: f64) -> Self {
qreal(value)
}
}

impl From<qreal> 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<u64> for QUInt64 {
fn from(value: u64) -> Self {
QUInt64(value)
}
}

impl From<QUInt64> 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<usize> for QUIntPtr {
fn from(value: usize) -> Self {
QUIntPtr(value)
}
}

impl From<QUIntPtr> 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<isize> for QSizeType {
fn from(value: isize) -> Self {
QSizeType(value)
}
}

impl From<QSizeType> 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;
}

0 comments on commit 18d370d

Please sign in to comment.