Skip to content

Commit 8a02883

Browse files
jnboothLeonMatthesKDAB
authored andcommitted
cxx-qt-lib: seal QFlagRepr trait
1 parent a519177 commit 8a02883

File tree

4 files changed

+71
-65
lines changed

4 files changed

+71
-65
lines changed

crates/cxx-qt-lib/src/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod qdatetime;
1818
pub use qdatetime::QDateTime;
1919

2020
mod qflags;
21-
pub use qflags::{QFlag, QFlags};
21+
pub use qflags::{QFlag, QFlagRepr, QFlags};
2222

2323
mod qhash;
2424
pub use qhash::{QHash, QHashPair, QHashPair_QString_QVariant, QHashPair_i32_QByteArray};

crates/cxx-qt-lib/src/core/qflags/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, N
1010

1111
mod qflag;
1212
pub use qflag::QFlag;
13-
use qflag::{QFlagExt, QFlagRepr};
13+
use qflag::QFlagExt;
1414

15-
mod util;
15+
mod repr;
16+
pub use repr::QFlagRepr;
1617

17-
type QFlagInt<T> = <T as QFlagExt>::Int;
18+
mod util;
1819

1920
/// The `QFlags<T>` class is a template class, where T is an enum type.
20-
/// QFlags is used throughout Qt for storing combinations of enum values.
21+
/// QFlags are used throughout Qt for storing combinations of enum values.
2122
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2223
#[repr(transparent)]
2324
pub struct QFlags<T: QFlag> {
24-
repr: QFlagInt<T>,
25+
repr: <T::Repr as QFlagRepr>::Int,
2526
}
2627

2728
impl<T: QFlag> Copy for QFlags<T> {}
@@ -55,12 +56,12 @@ impl<T: QFlag> QFlags<T> {
5556
}
5657

5758
/// Constructs a QFlags object representing the integer value *i*.
58-
pub const fn from_int(i: QFlagInt<T>) -> Self {
59+
pub const fn from_int(i: <T::Repr as QFlagRepr>::Int) -> Self {
5960
Self { repr: i }
6061
}
6162

6263
/// Returns the value stored in the QFlags object as an integer.
63-
pub const fn to_int(self) -> QFlagInt<T> {
64+
pub const fn to_int(self) -> <T::Repr as QFlagRepr>::Int {
6465
self.repr
6566
}
6667

crates/cxx-qt-lib/src/core/qflags/qflag.rs

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,10 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6-
use std::fmt::Debug;
7-
use std::hash::Hash;
8-
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
6+
use super::QFlagRepr;
97

108
use cxx::ExternType;
119

12-
pub trait QFlagRepr: Sized {
13-
/// Qt chooses the integer representation for a `QFlags<T>` as follows:
14-
///
15-
/// - If `T` is signed, use a signed integer. Otherwise, use an unsigned integer.
16-
/// - If `T` is 32 bits or less, use a 32-bit integer.
17-
/// - If `T` is 64 bits and the Qt version is at least 6.9, use a 64-bit integer.
18-
type Int: From<Self>
19-
+ Copy
20-
+ Debug
21-
+ Default
22-
+ Eq
23-
+ Ord
24-
+ Hash
25-
+ BitAnd<Output = Self::Int>
26-
+ BitAndAssign
27-
+ BitOr<Output = Self::Int>
28-
+ BitOrAssign
29-
+ BitXor<Output = Self::Int>
30-
+ BitXorAssign
31-
+ Not<Output = Self::Int>
32-
+ ExternType<Kind = cxx::kind::Trivial>;
33-
34-
const ZERO: Self::Int;
35-
}
36-
37-
macro_rules! impl_repr {
38-
($t:ty, $i:ty) => {
39-
impl QFlagRepr for $t {
40-
type Int = $i;
41-
42-
const ZERO: Self::Int = 0;
43-
}
44-
};
45-
}
46-
47-
impl_repr!(i8, i32);
48-
impl_repr!(i16, i32);
49-
impl_repr!(i32, i32);
50-
impl_repr!(u8, u32);
51-
impl_repr!(u16, u32);
52-
impl_repr!(u32, u32);
53-
54-
#[cfg(cxxqt_qt_version_at_least_6_9)]
55-
impl_repr!(i64, i64);
56-
#[cfg(cxxqt_qt_version_at_least_6_9)]
57-
impl_repr!(u64, u64);
58-
5910
/// # Safety
6011
///
6112
/// By writing the unsafe `QFlag` impl, the programmer asserts that the C++ namespace and type name
@@ -90,17 +41,13 @@ pub unsafe trait QFlag: Sized {
9041
}
9142

9243
/// Internal utility trait for converting `T` in a `QFlag<T>` to the corresponding integer type.
93-
pub trait QFlagExt: QFlag {
94-
type Int;
95-
96-
fn to_int(self) -> Self::Int;
44+
pub(super) trait QFlagExt: QFlag {
45+
fn to_int(self) -> <Self::Repr as QFlagRepr>::Int;
9746
}
9847

9948
impl<T: QFlag> QFlagExt for T {
100-
type Int = <<T as QFlag>::Repr as QFlagRepr>::Int;
101-
10249
#[inline(always)]
103-
fn to_int(self) -> Self::Int {
50+
fn to_int(self) -> <Self::Repr as QFlagRepr>::Int {
10451
self.to_repr().into()
10552
}
10653
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use std::fmt::Debug;
2+
use std::hash::Hash;
3+
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
4+
5+
use cxx::ExternType;
6+
7+
mod private {
8+
pub trait Sealed {}
9+
}
10+
11+
pub trait QFlagRepr: Sized + private::Sealed {
12+
/// Qt chooses the integer representation for a `QFlags<T>` as follows:
13+
///
14+
/// - If `T` is signed, use a signed integer. Otherwise, use an unsigned integer.
15+
/// - If `T` is 32 bits or less, use a 32-bit integer.
16+
/// - If `T` is 64 bits and the Qt version is at least 6.9, use a 64-bit integer.
17+
type Int: From<Self>
18+
+ Copy
19+
+ Debug
20+
+ Default
21+
+ Eq
22+
+ Ord
23+
+ Hash
24+
+ BitAnd<Output = Self::Int>
25+
+ BitAndAssign
26+
+ BitOr<Output = Self::Int>
27+
+ BitOrAssign
28+
+ BitXor<Output = Self::Int>
29+
+ BitXorAssign
30+
+ Not<Output = Self::Int>
31+
+ ExternType<Kind = cxx::kind::Trivial>;
32+
33+
const ZERO: Self::Int;
34+
}
35+
36+
macro_rules! impl_repr {
37+
($t:ty, $i:ty) => {
38+
impl private::Sealed for $t {}
39+
40+
impl QFlagRepr for $t {
41+
type Int = $i;
42+
43+
const ZERO: Self::Int = 0;
44+
}
45+
};
46+
}
47+
48+
impl_repr!(i8, i32);
49+
impl_repr!(i16, i32);
50+
impl_repr!(i32, i32);
51+
impl_repr!(u8, u32);
52+
impl_repr!(u16, u32);
53+
impl_repr!(u32, u32);
54+
55+
#[cfg(cxxqt_qt_version_at_least_6_9)]
56+
impl_repr!(i64, i64);
57+
#[cfg(cxxqt_qt_version_at_least_6_9)]
58+
impl_repr!(u64, u64);

0 commit comments

Comments
 (0)