Skip to content

Conversation

jnbooth
Copy link
Contributor

@jnbooth jnbooth commented Jul 19, 2025

Closes #1308.

Copy link

codecov bot commented Jul 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (c6710b7) to head (e7ba379).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #1314   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           75        75           
  Lines        12772     12784   +12     
=========================================
+ Hits         12772     12784   +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@angus-3d
Copy link

thank you @jnbooth ! Really appreciate it :-)

Copy link
Collaborator

@LeonMatthesKDAB LeonMatthesKDAB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jnbooth, thank you for for the contribution. Again, please excuse the delayed review.

The QQuaternion looks good. QGenericMatrix still has some room for improvement.

/// The QGenericMatrix class represents a quaternion consisting of a vector and scalar.
///
/// Qt Documentation: [QGenericMatrix](https://doc.qt.io/qt/qgenericmatrix.html#details)
#[repr(transparent)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[repr(transparent)]
#[repr(C)]

I think this needs to be repr(C), as otherwise it's not necessarily guaranteed that the layout matches the layout in C++, even with repr(transparent).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is for its layout to be that of [[f32; M]; N], rather than a struct with one [[f32; M]; N] member.


impl<const N: usize, const M: usize> QGenericMatrix<N, M> {
/// Constructs a matrix from floating-point `values` in row-major order.
pub const fn new(values: &[[f32; N]; M]) -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this takes the data by-reference and not by-value?
Taking it by-value would reduce the amount of copies needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it? Why?

let mut data = [[0.0; M]; N];
let mut i = 0;
let size = if M < N { M } else { N };
while i < size {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider replacing the while with:

for i in 0..size {
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently unsupported in const fn. We could un-const this function, but it seems useful to be able to declare a matrix as a constant.

pub const fn transposed(&self) -> QGenericMatrix<M, N> {
let mut transposed = [[0.0; N]; M];
let mut col = 0;
while col < N {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use for col in 0..N and for row in 0..M instead of while loops.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise unsupported by const fn. I generally default to making functions const if they can be, because people might find it useful, but I can get rid of it if you prefer.

Comment on lines +36 to +39
pub const fn data(&self) -> &[f32] {
// TODO: Replace with `array::as_flattened` once MSRV is 1.80.0.
unsafe { slice::from_raw_parts(self.data.as_ptr().cast(), N * M) }
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn data(&self) -> &[f32] {
// TODO: Replace with `array::as_flattened` once MSRV is 1.80.0.
unsafe { slice::from_raw_parts(self.data.as_ptr().cast(), N * M) }
}
pub const fn data(&self) -> &[f32; { N * M }] {
unsafe { *self.data.as_ptr().cast() }
}

Comment on lines +42 to +45
pub fn data_mut(&mut self) -> &mut [f32] {
// TODO: Replace with `array::as_flattened_mut` once MSRV is 1.80.0.
unsafe { slice::from_raw_parts_mut(self.data.as_mut_ptr().cast(), N * M) }
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn data_mut(&mut self) -> &mut [f32] {
// TODO: Replace with `array::as_flattened_mut` once MSRV is 1.80.0.
unsafe { slice::from_raw_parts_mut(self.data.as_mut_ptr().cast(), N * M) }
}
pub fn data_mut(&mut self) -> &mut [f32; { N * M }] {
unsafe { *self.data.as_mut_ptr().cast() }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out this does not work because "cannot move out of a raw pointer"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for QQuaternion (with variant conversion)
3 participants