fork download
  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@inria.fr>
  5. // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
  6. // Copyright (C) 2010-2013 Hauke Heibel <hauke.heibel@gmail.com>
  7. //
  8. // This Source Code Form is subject to the terms of the Mozilla
  9. // Public License v. 2.0. If a copy of the MPL was not distributed
  10. // with this file, You can obtain one at http://m...content-available-to-author-only...a.org/MPL/2.0/.
  11.  
  12. #ifndef EIGEN_MATRIXSTORAGE_H
  13. #define EIGEN_MATRIXSTORAGE_H
  14.  
  15. #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
  16. #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
  17. #else
  18. #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
  19. #endif
  20.  
  21. namespace Eigen {
  22.  
  23. namespace internal {
  24.  
  25. struct constructor_without_unaligned_array_assert {};
  26.  
  27. /** \internal
  28.   * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
  29.   * to 16 bytes boundary if the total size is a multiple of 16 bytes.
  30.   */
  31. template <typename T, int Size, int MatrixOrArrayOptions,
  32. int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
  33. : (((Size*sizeof(T))%16)==0) ? 16
  34. : 0 >
  35. struct plain_array
  36. {
  37. T array[Size];
  38.  
  39. plain_array()
  40. {
  41. EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
  42. }
  43.  
  44. plain_array(constructor_without_unaligned_array_assert)
  45. {
  46. EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
  47. }
  48. };
  49.  
  50. #if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
  51. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
  52. #elif EIGEN_GNUC_AT_LEAST(4,7)
  53. // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
  54. // See this bug report: http://g...content-available-to-author-only...u.org/bugzilla/show_bug.cgi?id=53900
  55. // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
  56. template<typename PtrType>
  57. EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
  58. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
  59.   eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \
  60.   && "this assertion is explained here: " \
  61.   "http://e...content-available-to-author-only...y.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
  62.   " **** READ THIS WEB PAGE !!! ****");
  63. #else
  64. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
  65.   eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
  66.   && "this assertion is explained here: " \
  67.   "http://e...content-available-to-author-only...y.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
  68.   " **** READ THIS WEB PAGE !!! ****");
  69. #endif
  70.  
  71. template <typename T, int Size, int MatrixOrArrayOptions>
  72. struct plain_array<T, Size, MatrixOrArrayOptions, 16>
  73. {
  74. EIGEN_USER_ALIGN16 T array[Size];
  75.  
  76. plain_array()
  77. {
  78. EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf);
  79. EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
  80. }
  81.  
  82. plain_array(constructor_without_unaligned_array_assert)
  83. {
  84. EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
  85. }
  86. };
  87.  
  88. template <typename T, int MatrixOrArrayOptions, int Alignment>
  89. struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
  90. {
  91. EIGEN_USER_ALIGN16 T array[1];
  92. plain_array() {}
  93. plain_array(constructor_without_unaligned_array_assert) {}
  94. };
  95.  
  96. } // end namespace internal
  97.  
  98. /** \internal
  99.   *
  100.   * \class DenseStorage
  101.   * \ingroup Core_Module
  102.   *
  103.   * \brief Stores the data of a matrix
  104.   *
  105.   * This class stores the data of fixed-size, dynamic-size or mixed matrices
  106.   * in a way as compact as possible.
  107.   *
  108.   * \sa Matrix
  109.   */
  110. template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage;
  111.  
  112. // purely fixed-size matrix
  113. template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage
  114. {
  115. internal::plain_array<T,Size,_Options> m_data;
  116. public:
  117. DenseStorage() {}
  118. DenseStorage(internal::constructor_without_unaligned_array_assert)
  119. : m_data(internal::constructor_without_unaligned_array_assert()) {}
  120. DenseStorage(const DenseStorage& other) : m_data(other.m_data) {}
  121. DenseStorage& operator=(const DenseStorage& other)
  122. {
  123. if (this != &other) m_data = other.m_data;
  124. return *this;
  125. }
  126. DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
  127. void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
  128. static DenseIndex rows(void) {return _Rows;}
  129. static DenseIndex cols(void) {return _Cols;}
  130. void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
  131. void resize(DenseIndex,DenseIndex,DenseIndex) {}
  132. const T *data() const { return m_data.array; }
  133. T *data() { return m_data.array; }
  134. };
  135.  
  136. // null matrix
  137. template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
  138. {
  139. public:
  140. DenseStorage() {}
  141. DenseStorage(internal::constructor_without_unaligned_array_assert) {}
  142. DenseStorage(const DenseStorage&) {}
  143. DenseStorage& operator=(const DenseStorage&) { return *this; }
  144. DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
  145. void swap(DenseStorage& ) {}
  146. static DenseIndex rows(void) {return _Rows;}
  147. static DenseIndex cols(void) {return _Cols;}
  148. void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
  149. void resize(DenseIndex,DenseIndex,DenseIndex) {}
  150. const T *data() const { return 0; }
  151. T *data() { return 0; }
  152. };
  153.  
  154. // more specializations for null matrices; these are necessary to resolve ambiguities
  155. template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options>
  156. : public DenseStorage<T, 0, 0, 0, _Options> { };
  157.  
  158. template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options>
  159. : public DenseStorage<T, 0, 0, 0, _Options> { };
  160.  
  161. template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options>
  162. : public DenseStorage<T, 0, 0, 0, _Options> { };
  163.  
  164. // dynamic-size matrix with fixed-size storage
  165. template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
  166. {
  167. internal::plain_array<T,Size,_Options> m_data;
  168. DenseIndex m_rows;
  169. DenseIndex m_cols;
  170. public:
  171. DenseStorage() : m_rows(0), m_cols(0) {}
  172. DenseStorage(internal::constructor_without_unaligned_array_assert)
  173. : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
  174. DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
  175. DenseStorage& operator=(const DenseStorage& other)
  176. {
  177. if (this != &other)
  178. {
  179. m_data = other.m_data;
  180. m_rows = other.m_rows;
  181. m_cols = other.m_cols;
  182. }
  183. return *this;
  184. }
  185. DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
  186. void swap(DenseStorage& other)
  187. { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
  188. DenseIndex rows() const {return m_rows;}
  189. DenseIndex cols() const {return m_cols;}
  190. void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
  191. void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
  192. const T *data() const { return m_data.array; }
  193. T *data() { return m_data.array; }
  194. };
  195.  
  196. // dynamic-size matrix with fixed-size storage and fixed width
  197. template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
  198. {
  199. internal::plain_array<T,Size,_Options> m_data;
  200. DenseIndex m_rows;
  201. public:
  202. DenseStorage() : m_rows(0) {}
  203. DenseStorage(internal::constructor_without_unaligned_array_assert)
  204. : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
  205. DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
  206. DenseStorage& operator=(const DenseStorage& other)
  207. {
  208. if (this != &other)
  209. {
  210. m_data = other.m_data;
  211. m_rows = other.m_rows;
  212. }
  213. return *this;
  214. }
  215. DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
  216. void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
  217. DenseIndex rows(void) const {return m_rows;}
  218. DenseIndex cols(void) const {return _Cols;}
  219. void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
  220. void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
  221. const T *data() const { return m_data.array; }
  222. T *data() { return m_data.array; }
  223. };
  224.  
  225. // dynamic-size matrix with fixed-size storage and fixed height
  226. template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
  227. {
  228. internal::plain_array<T,Size,_Options> m_data;
  229. DenseIndex m_cols;
  230. public:
  231. DenseStorage() : m_cols(0) {}
  232. DenseStorage(internal::constructor_without_unaligned_array_assert)
  233. : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
  234. DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
  235. DenseStorage& operator=(const DenseStorage& other)
  236. {
  237. if (this != &other)
  238. {
  239. m_data = other.m_data;
  240. m_cols = other.m_cols;
  241. }
  242. return *this;
  243. }
  244. DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
  245. void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
  246. DenseIndex rows(void) const {return _Rows;}
  247. DenseIndex cols(void) const {return m_cols;}
  248. void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
  249. void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
  250. const T *data() const { return m_data.array; }
  251. T *data() { return m_data.array; }
  252. };
  253.  
  254. // purely dynamic matrix.
  255. template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
  256. {
  257. T *m_data;
  258. DenseIndex m_rows;
  259. DenseIndex m_cols;
  260. public:
  261. DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
  262. DenseStorage(internal::constructor_without_unaligned_array_assert)
  263. : m_data(0), m_rows(0), m_cols(0) {}
  264. DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
  265. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols)
  266. { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
  267. DenseStorage(const DenseStorage& other)
  268. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*other.m_cols))
  269. , m_rows(other.m_rows)
  270. , m_cols(other.m_cols)
  271. {
  272. internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
  273. }
  274. DenseStorage& operator=(const DenseStorage& other)
  275. {
  276. if (this != &other)
  277. {
  278. DenseStorage tmp(other);
  279. this->swap(tmp);
  280. }
  281. return *this;
  282. }
  283. #ifdef EIGEN_HAVE_RVALUE_REFERENCES
  284. DenseStorage(DenseStorage&& other)
  285. : m_data(std::move(other.m_data))
  286. , m_rows(std::move(other.m_rows))
  287. , m_cols(std::move(other.m_cols))
  288. {
  289. other.m_data = nullptr;
  290. }
  291. DenseStorage& operator=(DenseStorage&& other)
  292. {
  293. using std::swap;
  294. swap(m_data, other.m_data);
  295. swap(m_rows, other.m_rows);
  296. swap(m_cols, other.m_cols);
  297. return *this;
  298. }
  299. #endif
  300. ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
  301. void swap(DenseStorage& other)
  302. { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
  303. DenseIndex rows(void) const {return m_rows;}
  304. DenseIndex cols(void) const {return m_cols;}
  305. void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
  306. {
  307. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
  308. m_rows = nbRows;
  309. m_cols = nbCols;
  310. }
  311. void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
  312. {
  313. if(size != m_rows*m_cols)
  314. {
  315. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
  316. if (size)
  317. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  318. else
  319. m_data = 0;
  320. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
  321. }
  322. m_rows = nbRows;
  323. m_cols = nbCols;
  324. }
  325. const T *data() const { return m_data; }
  326. T *data() { return m_data; }
  327. };
  328.  
  329. // matrix with dynamic width and fixed height (so that matrix has dynamic size).
  330. template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
  331. {
  332. T *m_data;
  333. DenseIndex m_cols;
  334. public:
  335. DenseStorage() : m_data(0), m_cols(0) {}
  336. DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
  337. DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
  338. { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
  339. DenseStorage(const DenseStorage& other)
  340. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols))
  341. , m_cols(other.m_cols)
  342. {
  343. internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
  344. }
  345. DenseStorage& operator=(const DenseStorage& other)
  346. {
  347. if (this != &other)
  348. {
  349. DenseStorage tmp(other);
  350. this->swap(tmp);
  351. }
  352. return *this;
  353. }
  354. #ifdef EIGEN_HAVE_RVALUE_REFERENCES
  355. DenseStorage(DenseStorage&& other)
  356. : m_data(std::move(other.m_data))
  357. , m_cols(std::move(other.m_cols))
  358. {
  359. other.m_data = nullptr;
  360. }
  361. DenseStorage& operator=(DenseStorage&& other)
  362. {
  363. using std::swap;
  364. swap(m_data, other.m_data);
  365. swap(m_cols, other.m_cols);
  366. return *this;
  367. }
  368. #endif
  369. ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
  370. void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
  371. static DenseIndex rows(void) {return _Rows;}
  372. DenseIndex cols(void) const {return m_cols;}
  373. void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
  374. {
  375. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
  376. m_cols = nbCols;
  377. }
  378. EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols)
  379. {
  380. if(size != _Rows*m_cols)
  381. {
  382. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
  383. if (size)
  384. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  385. else
  386. m_data = 0;
  387. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
  388. }
  389. m_cols = nbCols;
  390. }
  391. const T *data() const { return m_data; }
  392. T *data() { return m_data; }
  393. };
  394.  
  395. // matrix with dynamic height and fixed width (so that matrix has dynamic size).
  396. template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
  397. {
  398. T *m_data;
  399. DenseIndex m_rows;
  400. public:
  401. DenseStorage() : m_data(0), m_rows(0) {}
  402. DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
  403. DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
  404. { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
  405. DenseStorage(const DenseStorage& other)
  406. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols))
  407. , m_rows(other.m_rows)
  408. {
  409. internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
  410. }
  411. DenseStorage& operator=(const DenseStorage& other)
  412. {
  413. if (this != &other)
  414. {
  415. DenseStorage tmp(other);
  416. this->swap(tmp);
  417. }
  418. return *this;
  419. }
  420. #ifdef EIGEN_HAVE_RVALUE_REFERENCES
  421. DenseStorage(DenseStorage&& other)
  422. : m_data(std::move(other.m_data))
  423. , m_rows(std::move(other.m_rows))
  424. {
  425. other.m_data = nullptr;
  426. }
  427. DenseStorage& operator=(DenseStorage&& other)
  428. {
  429. using std::swap;
  430. swap(m_data, other.m_data);
  431. swap(m_rows, other.m_rows);
  432. return *this;
  433. }
  434. #endif
  435. ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
  436. void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
  437. DenseIndex rows(void) const {return m_rows;}
  438. static DenseIndex cols(void) {return _Cols;}
  439. void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
  440. {
  441. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
  442. m_rows = nbRows;
  443. }
  444. EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex)
  445. {
  446. if(size != m_rows*_Cols)
  447. {
  448. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
  449. if (size)
  450. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  451. else
  452. m_data = 0;
  453. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
  454. }
  455. m_rows = nbRows;
  456. }
  457. const T *data() const { return m_data; }
  458. T *data() { return m_data; }
  459. };
  460.  
  461. } // end namespace Eigen
  462.  
  463. #endif // EIGEN_MATRIX_H
  464.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty