Coverage Report

Created: 2026-04-01 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/math3d/qgenericmatrix.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#ifndef QGENERICMATRIX_H
6
#define QGENERICMATRIX_H
7
8
#include <QtGui/qtguiglobal.h>
9
#include <QtCore/qmetatype.h>
10
#include <QtCore/qdebug.h>
11
#include <QtCore/qdatastream.h>
12
13
QT_BEGIN_NAMESPACE
14
15
16
template <int N, int M, typename T>
17
class QGenericMatrix
18
{
19
public:
20
    QGenericMatrix();
21
0
    explicit QGenericMatrix(Qt::Initialization) {}
22
    explicit QGenericMatrix(const T *values);
23
24
    const T& operator()(int row, int column) const;
25
    T& operator()(int row, int column);
26
27
    bool isIdentity() const;
28
    void setToIdentity();
29
30
    void fill(T value);
31
32
    [[nodiscard]] QGenericMatrix<M, N, T> transposed() const;
33
34
    QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other);
35
    QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
36
    QGenericMatrix<N, M, T>& operator*=(T factor);
37
    QGenericMatrix<N, M, T>& operator/=(T divisor);
38
    bool operator==(const QGenericMatrix<N, M, T>& other) const;
39
    bool operator!=(const QGenericMatrix<N, M, T>& other) const;
40
41
    void copyDataTo(T *values) const;
42
43
0
    T *data() { return *m; }
44
    const T *data() const { return *m; }
45
0
    const T *constData() const { return *m; }
46
47
    template<int NN, int MM, typename TT>
48
    friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
49
    template<int NN, int MM, typename TT>
50
    friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
51
    template<int NN, int M1, int M2, typename TT>
52
    friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2);
53
    template<int NN, int MM, typename TT>
54
    friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix);
55
    template<int NN, int MM, typename TT>
56
    friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix);
57
    template<int NN, int MM, typename TT>
58
    friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor);
59
    template<int NN, int MM, typename TT>
60
    friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor);
61
62
private:
63
    T m[N][M];    // Column-major order to match OpenGL.
64
65
    template <int NN, int MM, typename TT>
66
    friend class QGenericMatrix;
67
};
68
template <int N, int M, typename T>
69
class QTypeInfo<QGenericMatrix<N, M, T> >
70
    : public QTypeInfoMerger<QGenericMatrix<N, M, T>, T>
71
{
72
};
73
74
template <int N, int M, typename T>
75
Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
76
0
{
77
0
    setToIdentity();
78
0
}
79
80
template <int N, int M, typename T>
81
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
82
{
83
    for (int col = 0; col < N; ++col)
84
        for (int row = 0; row < M; ++row)
85
            m[col][row] = values[row * N + col];
86
}
87
88
template <int N, int M, typename T>
89
Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
90
0
{
91
0
    Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
92
0
    return m[column][row];
93
0
}
94
95
template <int N, int M, typename T>
96
Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
97
0
{
98
0
    Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
99
0
    return m[column][row];
100
0
}
101
102
template <int N, int M, typename T>
103
Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
104
{
105
    for (int col = 0; col < N; ++col) {
106
        for (int row = 0; row < M; ++row) {
107
            if (row == col) {
108
                if (m[col][row] != 1.0f)
109
                    return false;
110
            } else {
111
                if (m[col][row] != 0.0f)
112
                    return false;
113
            }
114
        }
115
    }
116
    return true;
117
}
118
119
template <int N, int M, typename T>
120
Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
121
0
{
122
0
    for (int col = 0; col < N; ++col) {
123
0
        for (int row = 0; row < M; ++row) {
124
0
            if (row == col)
125
0
                m[col][row] = 1.0f;
126
0
            else
127
0
                m[col][row] = 0.0f;
128
0
        }
129
0
    }
130
0
}
131
132
template <int N, int M, typename T>
133
Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
134
{
135
    for (int col = 0; col < N; ++col)
136
        for (int row = 0; row < M; ++row)
137
            m[col][row] = value;
138
}
139
140
template <int N, int M, typename T>
141
Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const
142
{
143
    QGenericMatrix<M, N, T> result(Qt::Uninitialized);
144
    for (int row = 0; row < M; ++row)
145
        for (int col = 0; col < N; ++col)
146
            result.m[row][col] = m[col][row];
147
    return result;
148
}
149
150
template <int N, int M, typename T>
151
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other)
152
{
153
    for (int row = 0; row < M; ++row)
154
        for (int col = 0; col < N; ++col)
155
            m[col][row] += other.m[col][row];
156
    return *this;
157
}
158
159
template <int N, int M, typename T>
160
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
161
{
162
    for (int row = 0; row < M; ++row)
163
        for (int col = 0; col < N; ++col)
164
            m[col][row] -= other.m[col][row];
165
    return *this;
166
}
167
168
template <int N, int M, typename T>
169
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
170
{
171
    for (int row = 0; row < M; ++row)
172
        for (int col = 0; col < N; ++col)
173
            m[col][row] *= factor;
174
    return *this;
175
}
176
177
QT_WARNING_PUSH
178
QT_WARNING_DISABLE_FLOAT_COMPARE
179
180
template <int N, int M, typename T>
181
Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
182
{
183
    for (int row = 0; row < M; ++row)
184
        for (int col = 0; col < N; ++col)  {
185
            if (m[col][row] != other.m[col][row])
186
                return false;
187
        }
188
    return true;
189
}
190
191
template <int N, int M, typename T>
192
Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
193
{
194
    return !(*this == other);
195
}
196
197
QT_WARNING_POP
198
199
template <int N, int M, typename T>
200
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
201
{
202
    for (int row = 0; row < M; ++row)
203
        for (int col = 0; col < N; ++col)
204
            m[col][row] /= divisor;
205
    return *this;
206
}
207
208
template <int N, int M, typename T>
209
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
210
{
211
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
212
    for (int row = 0; row < M; ++row)
213
        for (int col = 0; col < N; ++col)
214
            result.m[col][row] = m1.m[col][row] + m2.m[col][row];
215
    return result;
216
}
217
218
template <int N, int M, typename T>
219
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
220
{
221
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
222
    for (int row = 0; row < M; ++row)
223
        for (int col = 0; col < N; ++col)
224
            result.m[col][row] = m1.m[col][row] - m2.m[col][row];
225
    return result;
226
}
227
228
template <int N, int M1, int M2, typename T>
229
Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
230
{
231
    QGenericMatrix<M1, M2, T> result(Qt::Uninitialized);
232
    for (int row = 0; row < M2; ++row) {
233
        for (int col = 0; col < M1; ++col) {
234
            T sum(0.0f);
235
            for (int j = 0; j < N; ++j)
236
                sum += m1.m[j][row] * m2.m[col][j];
237
            result.m[col][row] = sum;
238
        }
239
    }
240
    return result;
241
}
242
243
template <int N, int M, typename T>
244
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
245
{
246
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
247
    for (int row = 0; row < M; ++row)
248
        for (int col = 0; col < N; ++col)
249
            result.m[col][row] = -matrix.m[col][row];
250
    return result;
251
}
252
253
template <int N, int M, typename T>
254
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
255
{
256
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
257
    for (int row = 0; row < M; ++row)
258
        for (int col = 0; col < N; ++col)
259
            result.m[col][row] = matrix.m[col][row] * factor;
260
    return result;
261
}
262
263
template <int N, int M, typename T>
264
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
265
{
266
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
267
    for (int row = 0; row < M; ++row)
268
        for (int col = 0; col < N; ++col)
269
            result.m[col][row] = matrix.m[col][row] * factor;
270
    return result;
271
}
272
273
template <int N, int M, typename T>
274
Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
275
{
276
    QGenericMatrix<N, M, T> result(Qt::Uninitialized);
277
    for (int row = 0; row < M; ++row)
278
        for (int col = 0; col < N; ++col)
279
            result.m[col][row] = matrix.m[col][row] / divisor;
280
    return result;
281
}
282
283
template <int N, int M, typename T>
284
Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
285
{
286
    for (int col = 0; col < N; ++col)
287
        for (int row = 0; row < M; ++row)
288
            values[row * N + col] = T(m[col][row]);
289
}
290
291
// Define aliases for the useful variants of QGenericMatrix.
292
typedef QGenericMatrix<2, 2, float> QMatrix2x2;
293
typedef QGenericMatrix<2, 3, float> QMatrix2x3;
294
typedef QGenericMatrix<2, 4, float> QMatrix2x4;
295
typedef QGenericMatrix<3, 2, float> QMatrix3x2;
296
typedef QGenericMatrix<3, 3, float> QMatrix3x3;
297
typedef QGenericMatrix<3, 4, float> QMatrix3x4;
298
typedef QGenericMatrix<4, 2, float> QMatrix4x2;
299
typedef QGenericMatrix<4, 3, float> QMatrix4x3;
300
301
#ifndef QT_NO_DEBUG_STREAM
302
303
template <int N, int M, typename T>
304
QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
305
{
306
    QDebugStateSaver saver(dbg);
307
    dbg.nospace() << "QGenericMatrix<" << N << ", " << M
308
        << ", " << QMetaType::fromType<T>().name()
309
        << ">(" << Qt::endl << qSetFieldWidth(10);
310
    for (int row = 0; row < M; ++row) {
311
        for (int col = 0; col < N; ++col)
312
            dbg << m(row, col);
313
        dbg << Qt::endl;
314
    }
315
    dbg << qSetFieldWidth(0) << ')';
316
    return dbg;
317
}
318
319
#endif
320
321
#ifndef QT_NO_DATASTREAM
322
323
template <int N, int M, typename T>
324
QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
325
{
326
    for (int row = 0; row < M; ++row)
327
        for (int col = 0; col < N; ++col)
328
            stream << double(matrix(row, col));
329
    return stream;
330
}
331
332
template <int N, int M, typename T>
333
QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
334
{
335
    double x;
336
    for (int row = 0; row < M; ++row) {
337
        for (int col = 0; col < N; ++col) {
338
            stream >> x;
339
            matrix(row, col) = T(x);
340
        }
341
    }
342
    return stream;
343
}
344
345
#endif
346
347
QT_END_NAMESPACE
348
349
0
QT_DECL_METATYPE_EXTERN(QMatrix2x2, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<2, 2, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<2, 2, float> >::qt_metatype_id()
350
0
QT_DECL_METATYPE_EXTERN(QMatrix2x3, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<2, 3, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<2, 3, float> >::qt_metatype_id()
351
0
QT_DECL_METATYPE_EXTERN(QMatrix2x4, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<2, 4, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<2, 4, float> >::qt_metatype_id()
352
0
QT_DECL_METATYPE_EXTERN(QMatrix3x2, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<3, 2, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<3, 2, float> >::qt_metatype_id()
353
0
QT_DECL_METATYPE_EXTERN(QMatrix3x3, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<3, 3, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<3, 3, float> >::qt_metatype_id()
354
0
QT_DECL_METATYPE_EXTERN(QMatrix3x4, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<3, 4, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<3, 4, float> >::qt_metatype_id()
355
0
QT_DECL_METATYPE_EXTERN(QMatrix4x2, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<4, 2, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<4, 2, float> >::qt_metatype_id()
356
QT_DECL_METATYPE_EXTERN(QMatrix4x3, Q_GUI_EXPORT)
Unexecuted instantiation: int qRegisterNormalizedMetaType<QGenericMatrix<4, 3, float> >(QByteArray const&)
Unexecuted instantiation: QMetaTypeId<QGenericMatrix<4, 3, float> >::qt_metatype_id()
357
358
#endif