1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr> 5 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1 (at) 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 #include <QtCore/QVector> 15 #include <Eigen/Geometry> 16 #include <Eigen/QtAlignedMalloc> 17 18 template<typename MatrixType> 19 void check_qtvector_matrix(const MatrixType& m) 20 { 21 typedef typename MatrixType::Index Index; 22 23 Index rows = m.rows(); 24 Index 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> 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> 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 130 void test_qtvector() 131 { 132 // some non vectorizable fixed sizes 133 CALL_SUBTEST(check_qtvector_matrix(Vector2f())); 134 CALL_SUBTEST(check_qtvector_matrix(Matrix3f())); 135 CALL_SUBTEST(check_qtvector_matrix(Matrix3d())); 136 137 // some vectorizable fixed sizes 138 CALL_SUBTEST(check_qtvector_matrix(Matrix2f())); 139 CALL_SUBTEST(check_qtvector_matrix(Vector4f())); 140 CALL_SUBTEST(check_qtvector_matrix(Matrix4f())); 141 CALL_SUBTEST(check_qtvector_matrix(Matrix4d())); 142 143 // some dynamic sizes 144 CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1))); 145 CALL_SUBTEST(check_qtvector_matrix(VectorXd(20))); 146 CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20))); 147 CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10))); 148 149 // some Transform 150 CALL_SUBTEST(check_qtvector_transform(Affine2f())); 151 CALL_SUBTEST(check_qtvector_transform(Affine3f())); 152 CALL_SUBTEST(check_qtvector_transform(Affine3d())); 153 //CALL_SUBTEST(check_qtvector_transform(Transform4d())); 154 155 // some Quaternion 156 CALL_SUBTEST(check_qtvector_quaternion(Quaternionf())); 157 CALL_SUBTEST(check_qtvector_quaternion(Quaternionf())); 158 } 159