1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11 #define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5
12
13 #include "main.h"
14
15 #include <Eigen/Geometry>
16 #include <Eigen/QtAlignedMalloc>
17
18 #include <QtCore/QVector>
19
20 template<typename MatrixType>
check_qtvector_matrix(const MatrixType & m)21 void check_qtvector_matrix(const MatrixType& m)
22 {
23 int rows = m.rows();
24 int cols = m.cols();
25 MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
26 QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);
27 for(int i = 0; i < 20; i++)
28 {
29 VERIFY_IS_APPROX(w[i], y);
30 }
31 v[5] = x;
32 w[6] = v[5];
33 VERIFY_IS_APPROX(w[6], v[5]);
34 v = w;
35 for(int i = 0; i < 20; i++)
36 {
37 VERIFY_IS_APPROX(w[i], v[i]);
38 }
39
40 v.resize(21);
41 v[20] = x;
42 VERIFY_IS_APPROX(v[20], x);
43 v.fill(y,22);
44 VERIFY_IS_APPROX(v[21], y);
45 v.push_back(x);
46 VERIFY_IS_APPROX(v[22], x);
47 VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
48
49 // do a lot of push_back such that the vector gets internally resized
50 // (with memory reallocation)
51 MatrixType* ref = &w[0];
52 for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
53 v.push_back(w[i%w.size()]);
54 for(int i=23; i<v.size(); ++i)
55 {
56 VERIFY(v[i]==w[(i-23)%w.size()]);
57 }
58 }
59
60 template<typename TransformType>
check_qtvector_transform(const TransformType &)61 void check_qtvector_transform(const TransformType&)
62 {
63 typedef typename TransformType::MatrixType MatrixType;
64 TransformType x(MatrixType::Random()), y(MatrixType::Random());
65 QVector<TransformType> v(10), w(20, y);
66 v[5] = x;
67 w[6] = v[5];
68 VERIFY_IS_APPROX(w[6], v[5]);
69 v = w;
70 for(int i = 0; i < 20; i++)
71 {
72 VERIFY_IS_APPROX(w[i], v[i]);
73 }
74
75 v.resize(21);
76 v[20] = x;
77 VERIFY_IS_APPROX(v[20], x);
78 v.fill(y,22);
79 VERIFY_IS_APPROX(v[21], y);
80 v.push_back(x);
81 VERIFY_IS_APPROX(v[22], x);
82 VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
83
84 // do a lot of push_back such that the vector gets internally resized
85 // (with memory reallocation)
86 TransformType* ref = &w[0];
87 for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
88 v.push_back(w[i%w.size()]);
89 for(unsigned int i=23; int(i)<v.size(); ++i)
90 {
91 VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());
92 }
93 }
94
95 template<typename QuaternionType>
check_qtvector_quaternion(const QuaternionType &)96 void check_qtvector_quaternion(const QuaternionType&)
97 {
98 typedef typename QuaternionType::Coefficients Coefficients;
99 QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
100 QVector<QuaternionType> v(10), w(20, y);
101 v[5] = x;
102 w[6] = v[5];
103 VERIFY_IS_APPROX(w[6], v[5]);
104 v = w;
105 for(int i = 0; i < 20; i++)
106 {
107 VERIFY_IS_APPROX(w[i], v[i]);
108 }
109
110 v.resize(21);
111 v[20] = x;
112 VERIFY_IS_APPROX(v[20], x);
113 v.fill(y,22);
114 VERIFY_IS_APPROX(v[21], y);
115 v.push_back(x);
116 VERIFY_IS_APPROX(v[22], x);
117 VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
118
119 // do a lot of push_back such that the vector gets internally resized
120 // (with memory reallocation)
121 QuaternionType* ref = &w[0];
122 for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
123 v.push_back(w[i%w.size()]);
124 for(unsigned int i=23; int(i)<v.size(); ++i)
125 {
126 VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());
127 }
128 }
129
test_eigen2_qtvector()130 void test_eigen2_qtvector()
131 {
132 // some non vectorizable fixed sizes
133 CALL_SUBTEST_1(check_qtvector_matrix(Vector2f()));
134 CALL_SUBTEST_1(check_qtvector_matrix(Matrix3f()));
135 CALL_SUBTEST_1(check_qtvector_matrix(Matrix3d()));
136
137 // some vectorizable fixed sizes
138 CALL_SUBTEST_2(check_qtvector_matrix(Matrix2f()));
139 CALL_SUBTEST_2(check_qtvector_matrix(Vector4f()));
140 CALL_SUBTEST_2(check_qtvector_matrix(Matrix4f()));
141 CALL_SUBTEST_2(check_qtvector_matrix(Matrix4d()));
142
143 // some dynamic sizes
144 CALL_SUBTEST_3(check_qtvector_matrix(MatrixXd(1,1)));
145 CALL_SUBTEST_3(check_qtvector_matrix(VectorXd(20)));
146 CALL_SUBTEST_3(check_qtvector_matrix(RowVectorXf(20)));
147 CALL_SUBTEST_3(check_qtvector_matrix(MatrixXcf(10,10)));
148
149 // some Transform
150 CALL_SUBTEST_4(check_qtvector_transform(Transform2f()));
151 CALL_SUBTEST_4(check_qtvector_transform(Transform3f()));
152 CALL_SUBTEST_4(check_qtvector_transform(Transform3d()));
153 //CALL_SUBTEST_4(check_qtvector_transform(Transform4d()));
154
155 // some Quaternion
156 CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));
157 CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));
158 }
159