stdlist_overload.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  5. // Copyright (C) 2010 Hauke Heibel <hauke.heibel@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. #include "main.h"
  11. #include <Eigen/StdList>
  12. #include <Eigen/Geometry>
  13. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Vector4f)
  14. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix2f)
  15. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix4f)
  16. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix4d)
  17. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Affine3f)
  18. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Affine3d)
  19. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Quaternionf)
  20. EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Quaterniond)
  21. template <class Container, class Position>
  22. typename Container::iterator get(Container & c, Position position)
  23. {
  24. typename Container::iterator it = c.begin();
  25. std::advance(it, position);
  26. return it;
  27. }
  28. template <class Container, class Position, class Value>
  29. void set(Container & c, Position position, const Value & value)
  30. {
  31. typename Container::iterator it = c.begin();
  32. std::advance(it, position);
  33. *it = value;
  34. }
  35. template<typename MatrixType>
  36. void check_stdlist_matrix(const MatrixType& m)
  37. {
  38. Index rows = m.rows();
  39. Index cols = m.cols();
  40. MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
  41. std::list<MatrixType> v(10, MatrixType::Zero(rows,cols)), w(20, y);
  42. typename std::list<MatrixType>::iterator itv = get(v, 5);
  43. typename std::list<MatrixType>::iterator itw = get(w, 6);
  44. *itv = x;
  45. *itw = *itv;
  46. VERIFY_IS_APPROX(*itw, *itv);
  47. v = w;
  48. itv = v.begin();
  49. itw = w.begin();
  50. for(int i = 0; i < 20; i++)
  51. {
  52. VERIFY_IS_APPROX(*itw, *itv);
  53. ++itv;
  54. ++itw;
  55. }
  56. v.resize(21);
  57. set(v, 20, x);
  58. VERIFY_IS_APPROX(*get(v, 20), x);
  59. v.resize(22,y);
  60. VERIFY_IS_APPROX(*get(v, 21), y);
  61. v.push_back(x);
  62. VERIFY_IS_APPROX(*get(v, 22), x);
  63. // do a lot of push_back such that the list gets internally resized
  64. // (with memory reallocation)
  65. MatrixType* ref = &(*get(w, 0));
  66. for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i)
  67. v.push_back(*get(w, i%w.size()));
  68. for(unsigned int i=23; i<v.size(); ++i)
  69. {
  70. VERIFY((*get(v, i))==(*get(w, (i-23)%w.size())));
  71. }
  72. }
  73. template<typename TransformType>
  74. void check_stdlist_transform(const TransformType&)
  75. {
  76. typedef typename TransformType::MatrixType MatrixType;
  77. TransformType x(MatrixType::Random()), y(MatrixType::Random()), ti=TransformType::Identity();
  78. std::list<TransformType> v(10,ti), w(20, y);
  79. typename std::list<TransformType>::iterator itv = get(v, 5);
  80. typename std::list<TransformType>::iterator itw = get(w, 6);
  81. *itv = x;
  82. *itw = *itv;
  83. VERIFY_IS_APPROX(*itw, *itv);
  84. v = w;
  85. itv = v.begin();
  86. itw = w.begin();
  87. for(int i = 0; i < 20; i++)
  88. {
  89. VERIFY_IS_APPROX(*itw, *itv);
  90. ++itv;
  91. ++itw;
  92. }
  93. v.resize(21, ti);
  94. set(v, 20, x);
  95. VERIFY_IS_APPROX(*get(v, 20), x);
  96. v.resize(22,y);
  97. VERIFY_IS_APPROX(*get(v, 21), y);
  98. v.push_back(x);
  99. VERIFY_IS_APPROX(*get(v, 22), x);
  100. // do a lot of push_back such that the list gets internally resized
  101. // (with memory reallocation)
  102. TransformType* ref = &(*get(w, 0));
  103. for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i)
  104. v.push_back(*get(w, i%w.size()));
  105. for(unsigned int i=23; i<v.size(); ++i)
  106. {
  107. VERIFY(get(v, i)->matrix()==get(w, (i-23)%w.size())->matrix());
  108. }
  109. }
  110. template<typename QuaternionType>
  111. void check_stdlist_quaternion(const QuaternionType&)
  112. {
  113. typedef typename QuaternionType::Coefficients Coefficients;
  114. QuaternionType x(Coefficients::Random()), y(Coefficients::Random()), qi=QuaternionType::Identity();
  115. std::list<QuaternionType> v(10,qi), w(20, y);
  116. typename std::list<QuaternionType>::iterator itv = get(v, 5);
  117. typename std::list<QuaternionType>::iterator itw = get(w, 6);
  118. *itv = x;
  119. *itw = *itv;
  120. VERIFY_IS_APPROX(*itw, *itv);
  121. v = w;
  122. itv = v.begin();
  123. itw = w.begin();
  124. for(int i = 0; i < 20; i++)
  125. {
  126. VERIFY_IS_APPROX(*itw, *itv);
  127. ++itv;
  128. ++itw;
  129. }
  130. v.resize(21,qi);
  131. set(v, 20, x);
  132. VERIFY_IS_APPROX(*get(v, 20), x);
  133. v.resize(22,y);
  134. VERIFY_IS_APPROX(*get(v, 21), y);
  135. v.push_back(x);
  136. VERIFY_IS_APPROX(*get(v, 22), x);
  137. // do a lot of push_back such that the list gets internally resized
  138. // (with memory reallocation)
  139. QuaternionType* ref = &(*get(w, 0));
  140. for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i)
  141. v.push_back(*get(w, i%w.size()));
  142. for(unsigned int i=23; i<v.size(); ++i)
  143. {
  144. VERIFY(get(v, i)->coeffs()==get(w, (i-23)%w.size())->coeffs());
  145. }
  146. }
  147. EIGEN_DECLARE_TEST(stdlist_overload)
  148. {
  149. // some non vectorizable fixed sizes
  150. CALL_SUBTEST_1(check_stdlist_matrix(Vector2f()));
  151. CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f()));
  152. CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d()));
  153. // some vectorizable fixed sizes
  154. CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f()));
  155. CALL_SUBTEST_1(check_stdlist_matrix(Vector4f()));
  156. CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f()));
  157. CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d()));
  158. // some dynamic sizes
  159. CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1)));
  160. CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20)));
  161. CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20)));
  162. CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10)));
  163. // some Transform
  164. CALL_SUBTEST_4(check_stdlist_transform(Affine2f())); // does not need the specialization (2+1)^2 = 9
  165. CALL_SUBTEST_4(check_stdlist_transform(Affine3f()));
  166. CALL_SUBTEST_4(check_stdlist_transform(Affine3d()));
  167. // some Quaternion
  168. CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf()));
  169. CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond()));
  170. }