DenseStorage.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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://mozilla.org/MPL/2.0/.
  11. #ifndef EIGEN_MATRIXSTORAGE_H
  12. #define EIGEN_MATRIXSTORAGE_H
  13. #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
  14. #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) X; EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
  15. #else
  16. #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
  17. #endif
  18. namespace Eigen {
  19. namespace internal {
  20. struct constructor_without_unaligned_array_assert {};
  21. template<typename T, int Size>
  22. EIGEN_DEVICE_FUNC
  23. void check_static_allocation_size()
  24. {
  25. // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
  26. #if EIGEN_STACK_ALLOCATION_LIMIT
  27. EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
  28. #endif
  29. }
  30. /** \internal
  31. * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
  32. * to 16 bytes boundary if the total size is a multiple of 16 bytes.
  33. */
  34. template <typename T, int Size, int MatrixOrArrayOptions,
  35. int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
  36. : compute_default_alignment<T,Size>::value >
  37. struct plain_array
  38. {
  39. T array[Size];
  40. EIGEN_DEVICE_FUNC
  41. plain_array()
  42. {
  43. check_static_allocation_size<T,Size>();
  44. }
  45. EIGEN_DEVICE_FUNC
  46. plain_array(constructor_without_unaligned_array_assert)
  47. {
  48. check_static_allocation_size<T,Size>();
  49. }
  50. };
  51. #if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
  52. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
  53. #elif EIGEN_GNUC_AT_LEAST(4,7)
  54. // 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.
  55. // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
  56. // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
  57. template<typename PtrType>
  58. EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
  59. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
  60. eigen_assert((internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (sizemask)) == 0 \
  61. && "this assertion is explained here: " \
  62. "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
  63. " **** READ THIS WEB PAGE !!! ****");
  64. #else
  65. #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
  66. eigen_assert((internal::UIntPtr(array) & (sizemask)) == 0 \
  67. && "this assertion is explained here: " \
  68. "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
  69. " **** READ THIS WEB PAGE !!! ****");
  70. #endif
  71. template <typename T, int Size, int MatrixOrArrayOptions>
  72. struct plain_array<T, Size, MatrixOrArrayOptions, 8>
  73. {
  74. EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
  75. EIGEN_DEVICE_FUNC
  76. plain_array()
  77. {
  78. EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
  79. check_static_allocation_size<T,Size>();
  80. }
  81. EIGEN_DEVICE_FUNC
  82. plain_array(constructor_without_unaligned_array_assert)
  83. {
  84. check_static_allocation_size<T,Size>();
  85. }
  86. };
  87. template <typename T, int Size, int MatrixOrArrayOptions>
  88. struct plain_array<T, Size, MatrixOrArrayOptions, 16>
  89. {
  90. EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
  91. EIGEN_DEVICE_FUNC
  92. plain_array()
  93. {
  94. EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
  95. check_static_allocation_size<T,Size>();
  96. }
  97. EIGEN_DEVICE_FUNC
  98. plain_array(constructor_without_unaligned_array_assert)
  99. {
  100. check_static_allocation_size<T,Size>();
  101. }
  102. };
  103. template <typename T, int Size, int MatrixOrArrayOptions>
  104. struct plain_array<T, Size, MatrixOrArrayOptions, 32>
  105. {
  106. EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
  107. EIGEN_DEVICE_FUNC
  108. plain_array()
  109. {
  110. EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
  111. check_static_allocation_size<T,Size>();
  112. }
  113. EIGEN_DEVICE_FUNC
  114. plain_array(constructor_without_unaligned_array_assert)
  115. {
  116. check_static_allocation_size<T,Size>();
  117. }
  118. };
  119. template <typename T, int Size, int MatrixOrArrayOptions>
  120. struct plain_array<T, Size, MatrixOrArrayOptions, 64>
  121. {
  122. EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
  123. EIGEN_DEVICE_FUNC
  124. plain_array()
  125. {
  126. EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
  127. check_static_allocation_size<T,Size>();
  128. }
  129. EIGEN_DEVICE_FUNC
  130. plain_array(constructor_without_unaligned_array_assert)
  131. {
  132. check_static_allocation_size<T,Size>();
  133. }
  134. };
  135. template <typename T, int MatrixOrArrayOptions, int Alignment>
  136. struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
  137. {
  138. T array[1];
  139. EIGEN_DEVICE_FUNC plain_array() {}
  140. EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
  141. };
  142. } // end namespace internal
  143. /** \internal
  144. *
  145. * \class DenseStorage
  146. * \ingroup Core_Module
  147. *
  148. * \brief Stores the data of a matrix
  149. *
  150. * This class stores the data of fixed-size, dynamic-size or mixed matrices
  151. * in a way as compact as possible.
  152. *
  153. * \sa Matrix
  154. */
  155. template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage;
  156. // purely fixed-size matrix
  157. template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage
  158. {
  159. internal::plain_array<T,Size,_Options> m_data;
  160. public:
  161. EIGEN_DEVICE_FUNC DenseStorage() {
  162. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
  163. }
  164. EIGEN_DEVICE_FUNC
  165. explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
  166. : m_data(internal::constructor_without_unaligned_array_assert()) {}
  167. EIGEN_DEVICE_FUNC
  168. DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
  169. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
  170. }
  171. EIGEN_DEVICE_FUNC
  172. DenseStorage& operator=(const DenseStorage& other)
  173. {
  174. if (this != &other) m_data = other.m_data;
  175. return *this;
  176. }
  177. EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
  178. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  179. eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
  180. EIGEN_UNUSED_VARIABLE(size);
  181. EIGEN_UNUSED_VARIABLE(rows);
  182. EIGEN_UNUSED_VARIABLE(cols);
  183. }
  184. EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
  185. EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
  186. EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
  187. EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
  188. EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
  189. EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
  190. EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
  191. };
  192. // null matrix
  193. template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
  194. {
  195. public:
  196. EIGEN_DEVICE_FUNC DenseStorage() {}
  197. EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
  198. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {}
  199. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
  200. EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
  201. EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
  202. EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
  203. EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
  204. EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
  205. EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
  206. EIGEN_DEVICE_FUNC const T *data() const { return 0; }
  207. EIGEN_DEVICE_FUNC T *data() { return 0; }
  208. };
  209. // more specializations for null matrices; these are necessary to resolve ambiguities
  210. template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options>
  211. : public DenseStorage<T, 0, 0, 0, _Options> { };
  212. template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options>
  213. : public DenseStorage<T, 0, 0, 0, _Options> { };
  214. template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options>
  215. : public DenseStorage<T, 0, 0, 0, _Options> { };
  216. // dynamic-size matrix with fixed-size storage
  217. template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
  218. {
  219. internal::plain_array<T,Size,_Options> m_data;
  220. Index m_rows;
  221. Index m_cols;
  222. public:
  223. EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
  224. EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
  225. : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
  226. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
  227. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  228. {
  229. if (this != &other)
  230. {
  231. m_data = other.m_data;
  232. m_rows = other.m_rows;
  233. m_cols = other.m_cols;
  234. }
  235. return *this;
  236. }
  237. EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
  238. EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
  239. { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
  240. EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
  241. EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
  242. EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
  243. EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
  244. EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
  245. EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
  246. };
  247. // dynamic-size matrix with fixed-size storage and fixed width
  248. template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
  249. {
  250. internal::plain_array<T,Size,_Options> m_data;
  251. Index m_rows;
  252. public:
  253. EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
  254. EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
  255. : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
  256. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
  257. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  258. {
  259. if (this != &other)
  260. {
  261. m_data = other.m_data;
  262. m_rows = other.m_rows;
  263. }
  264. return *this;
  265. }
  266. EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
  267. EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
  268. EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
  269. EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
  270. EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
  271. EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
  272. EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
  273. EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
  274. };
  275. // dynamic-size matrix with fixed-size storage and fixed height
  276. template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
  277. {
  278. internal::plain_array<T,Size,_Options> m_data;
  279. Index m_cols;
  280. public:
  281. EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
  282. EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
  283. : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
  284. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
  285. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  286. {
  287. if (this != &other)
  288. {
  289. m_data = other.m_data;
  290. m_cols = other.m_cols;
  291. }
  292. return *this;
  293. }
  294. EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
  295. EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
  296. EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
  297. EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
  298. void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
  299. void resize(Index, Index, Index cols) { m_cols = cols; }
  300. EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
  301. EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
  302. };
  303. // purely dynamic matrix.
  304. template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
  305. {
  306. T *m_data;
  307. Index m_rows;
  308. Index m_cols;
  309. public:
  310. EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
  311. EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
  312. : m_data(0), m_rows(0), m_cols(0) {}
  313. EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
  314. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
  315. {
  316. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  317. eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
  318. }
  319. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
  320. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*other.m_cols))
  321. , m_rows(other.m_rows)
  322. , m_cols(other.m_cols)
  323. {
  324. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
  325. internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
  326. }
  327. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  328. {
  329. if (this != &other)
  330. {
  331. DenseStorage tmp(other);
  332. this->swap(tmp);
  333. }
  334. return *this;
  335. }
  336. #if EIGEN_HAS_RVALUE_REFERENCES
  337. EIGEN_DEVICE_FUNC
  338. DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
  339. : m_data(std::move(other.m_data))
  340. , m_rows(std::move(other.m_rows))
  341. , m_cols(std::move(other.m_cols))
  342. {
  343. other.m_data = nullptr;
  344. other.m_rows = 0;
  345. other.m_cols = 0;
  346. }
  347. EIGEN_DEVICE_FUNC
  348. DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
  349. {
  350. using std::swap;
  351. swap(m_data, other.m_data);
  352. swap(m_rows, other.m_rows);
  353. swap(m_cols, other.m_cols);
  354. return *this;
  355. }
  356. #endif
  357. EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
  358. EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
  359. { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
  360. EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
  361. EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
  362. void conservativeResize(Index size, Index rows, Index cols)
  363. {
  364. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
  365. m_rows = rows;
  366. m_cols = cols;
  367. }
  368. EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols)
  369. {
  370. if(size != m_rows*m_cols)
  371. {
  372. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
  373. if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
  374. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  375. else
  376. m_data = 0;
  377. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  378. }
  379. m_rows = rows;
  380. m_cols = cols;
  381. }
  382. EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
  383. EIGEN_DEVICE_FUNC T *data() { return m_data; }
  384. };
  385. // matrix with dynamic width and fixed height (so that matrix has dynamic size).
  386. template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
  387. {
  388. T *m_data;
  389. Index m_cols;
  390. public:
  391. EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {}
  392. explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
  393. EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
  394. {
  395. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  396. eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0);
  397. EIGEN_UNUSED_VARIABLE(rows);
  398. }
  399. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
  400. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols))
  401. , m_cols(other.m_cols)
  402. {
  403. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows)
  404. internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
  405. }
  406. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  407. {
  408. if (this != &other)
  409. {
  410. DenseStorage tmp(other);
  411. this->swap(tmp);
  412. }
  413. return *this;
  414. }
  415. #if EIGEN_HAS_RVALUE_REFERENCES
  416. EIGEN_DEVICE_FUNC
  417. DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
  418. : m_data(std::move(other.m_data))
  419. , m_cols(std::move(other.m_cols))
  420. {
  421. other.m_data = nullptr;
  422. other.m_cols = 0;
  423. }
  424. EIGEN_DEVICE_FUNC
  425. DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
  426. {
  427. using std::swap;
  428. swap(m_data, other.m_data);
  429. swap(m_cols, other.m_cols);
  430. return *this;
  431. }
  432. #endif
  433. EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
  434. EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
  435. EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
  436. EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
  437. EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
  438. {
  439. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
  440. m_cols = cols;
  441. }
  442. EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols)
  443. {
  444. if(size != _Rows*m_cols)
  445. {
  446. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
  447. if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
  448. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  449. else
  450. m_data = 0;
  451. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  452. }
  453. m_cols = cols;
  454. }
  455. EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
  456. EIGEN_DEVICE_FUNC T *data() { return m_data; }
  457. };
  458. // matrix with dynamic height and fixed width (so that matrix has dynamic size).
  459. template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
  460. {
  461. T *m_data;
  462. Index m_rows;
  463. public:
  464. EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {}
  465. explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
  466. EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
  467. {
  468. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  469. eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols);
  470. EIGEN_UNUSED_VARIABLE(cols);
  471. }
  472. EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
  473. : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols))
  474. , m_rows(other.m_rows)
  475. {
  476. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols)
  477. internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
  478. }
  479. EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
  480. {
  481. if (this != &other)
  482. {
  483. DenseStorage tmp(other);
  484. this->swap(tmp);
  485. }
  486. return *this;
  487. }
  488. #if EIGEN_HAS_RVALUE_REFERENCES
  489. EIGEN_DEVICE_FUNC
  490. DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
  491. : m_data(std::move(other.m_data))
  492. , m_rows(std::move(other.m_rows))
  493. {
  494. other.m_data = nullptr;
  495. other.m_rows = 0;
  496. }
  497. EIGEN_DEVICE_FUNC
  498. DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
  499. {
  500. using std::swap;
  501. swap(m_data, other.m_data);
  502. swap(m_rows, other.m_rows);
  503. return *this;
  504. }
  505. #endif
  506. EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
  507. EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
  508. EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
  509. EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
  510. void conservativeResize(Index size, Index rows, Index)
  511. {
  512. m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
  513. m_rows = rows;
  514. }
  515. EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index)
  516. {
  517. if(size != m_rows*_Cols)
  518. {
  519. internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
  520. if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
  521. m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
  522. else
  523. m_data = 0;
  524. EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
  525. }
  526. m_rows = rows;
  527. }
  528. EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
  529. EIGEN_DEVICE_FUNC T *data() { return m_data; }
  530. };
  531. } // end namespace Eigen
  532. #endif // EIGEN_MATRIX_H