DenseStorage.h
Go to the documentation of this file.
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 
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(X) X; EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
17 #else
18  #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
19 #endif
20 
21 #include "./InternalHeaderCheck.h"
22 
23 namespace Eigen {
24 
25 namespace internal {
26 
27 struct constructor_without_unaligned_array_assert {};
28 
29 template <typename T, int Size>
31 // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
32 #if EIGEN_STACK_ALLOCATION_LIMIT
33  EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
34 #endif
35 }
36 
41 template <typename T, int Size, int MatrixOrArrayOptions,
42  int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
43  : compute_default_alignment<T,Size>::value >
44 struct plain_array
45 {
46  T array[Size];
47 
48  EIGEN_DEVICE_FUNC constexpr plain_array() { check_static_allocation_size<T, Size>(); }
49 
50  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
51  check_static_allocation_size<T, Size>();
52  }
53 };
54 
55 #if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
56  #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
57 #else
58  #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
59  eigen_assert((internal::is_constant_evaluated() || (std::uintptr_t(array) & (sizemask)) == 0) \
60  && "this assertion is explained here: " \
61  "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
62  " **** READ THIS WEB PAGE !!! ****");
63 #endif
64 
65 template <typename T, int Size, int MatrixOrArrayOptions>
66 struct plain_array<T, Size, MatrixOrArrayOptions, 8>
67 {
69 
70  EIGEN_DEVICE_FUNC constexpr plain_array() {
72  check_static_allocation_size<T,Size>();
73  }
74 
75  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
76  check_static_allocation_size<T, Size>();
77  }
78 };
79 
80 template <typename T, int Size, int MatrixOrArrayOptions>
81 struct plain_array<T, Size, MatrixOrArrayOptions, 16>
82 {
84 
85  EIGEN_DEVICE_FUNC constexpr plain_array() {
87  check_static_allocation_size<T,Size>();
88  }
89 
90  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
91  check_static_allocation_size<T, Size>();
92  }
93 };
94 
95 template <typename T, int Size, int MatrixOrArrayOptions>
96 struct plain_array<T, Size, MatrixOrArrayOptions, 32>
97 {
99 
100  EIGEN_DEVICE_FUNC constexpr plain_array() {
102  check_static_allocation_size<T,Size>();
103  }
104 
105  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
106  check_static_allocation_size<T, Size>();
107  }
108 };
109 
110 template <typename T, int Size, int MatrixOrArrayOptions>
111 struct plain_array<T, Size, MatrixOrArrayOptions, 64>
112 {
113  EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
114 
115  EIGEN_DEVICE_FUNC constexpr plain_array() {
117  check_static_allocation_size<T,Size>();
118  }
119 
120  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
121  check_static_allocation_size<T, Size>();
122  }
123 };
124 
125 template <typename T, int MatrixOrArrayOptions, int Alignment>
126 struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
127 {
128  T array[1];
129  EIGEN_DEVICE_FUNC constexpr plain_array() {}
130  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {}
131 };
132 
133 struct plain_array_helper {
134  template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
135  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
136  static void copy(const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size,
137  plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) {
138  smart_copy(src.array, src.array + size, dst.array);
139  }
140 
141  template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
142  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
143  static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a, const Eigen::Index a_size,
144  plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b, const Eigen::Index b_size) {
145  if (a_size < b_size) {
146  std::swap_ranges(b.array, b.array + a_size, a.array);
147  smart_move(b.array + a_size, b.array + b_size, a.array + a_size);
148  } else if (a_size > b_size) {
149  std::swap_ranges(a.array, a.array + b_size, b.array);
150  smart_move(a.array + b_size, a.array + a_size, b.array + b_size);
151  } else {
152  std::swap_ranges(a.array, a.array + a_size, b.array);
153  }
154  }
155 };
156 
157 } // end namespace internal
158 
171 template<typename T, int Size, int Rows_, int Cols_, int Options_> class DenseStorage;
172 
173 // purely fixed-size matrix
174 template<typename T, int Size, int Rows_, int Cols_, int Options_> class DenseStorage
175 {
176  internal::plain_array<T,Size,Options_> m_data;
177  public:
180  }
181  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
182  : m_data(internal::constructor_without_unaligned_array_assert()) {}
183 #if defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
184  EIGEN_DEVICE_FUNC constexpr
185  DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
187  }
188 #else
189  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) = default;
190 #endif
191  EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) = default;
196  eigen_internal_assert(size == rows * cols && rows == Rows_ && cols == Cols_);
200  }
202  numext::swap(m_data, other.m_data);
203  }
204  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
205  EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT { return Cols_; }
207  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index) {}
208  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
209  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
210 };
211 
212 // null matrix
213 template<typename T, int Rows_, int Cols_, int Options_>
214 class DenseStorage<T, 0, Rows_, Cols_, Options_>
215 {
216  public:
217  static_assert(Rows_ * Cols_ == 0, "The fixed number of rows times columns must equal the storage size.");
218  EIGEN_DEVICE_FUNC constexpr DenseStorage() {}
219  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) {}
220  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) {}
221  EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) { return *this; }
222  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index,Index,Index) {}
223  EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage& ) {}
224  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
225  EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
226  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index,Index,Index) {}
227  EIGEN_DEVICE_FUNC constexpr void resize(Index,Index,Index) {}
228  EIGEN_DEVICE_FUNC constexpr const T *data() const { return 0; }
229  EIGEN_DEVICE_FUNC constexpr T *data() { return 0; }
230 };
231 
232 // more specializations for null matrices; these are necessary to resolve ambiguities
233 template<typename T, int Options_>
234 class DenseStorage<T, 0, Dynamic, Dynamic, Options_> {
235  Index m_rows;
236  Index m_cols;
237  public:
238  EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
239  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
240  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_rows(other.m_rows), m_cols(other.m_cols) {}
241  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
242  m_rows = other.m_rows;
243  m_cols = other.m_cols;
244  return *this;
245  }
246  EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {
247  eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
248  }
249  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
250  numext::swap(m_rows,other.m_rows);
251  numext::swap(m_cols,other.m_cols);
252  }
255  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) {
256  m_rows = rows;
257  m_cols = cols;
258  eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
259  }
261  m_rows = rows;
262  m_cols = cols;
263  eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
264  }
265  EIGEN_DEVICE_FUNC const T *data() const { return nullptr; }
266  EIGEN_DEVICE_FUNC T *data() { return nullptr; }
267 };
268 
269 template<typename T, int Rows_, int Options_>
270 class DenseStorage<T, 0, Rows_, Dynamic, Options_> {
271  Index m_cols;
272  public:
273  EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
274  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
275  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_cols(other.m_cols) {}
276  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
277  m_cols = other.m_cols;
278  return *this;
279  }
280  EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {
281  eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
282  }
283  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
284  numext::swap(m_cols, other.m_cols);
285  }
286  EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
287  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
288  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) {
289  m_cols = cols;
290  eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
291  }
293  m_cols = cols;
294  eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
295  }
296  EIGEN_DEVICE_FUNC const T *data() const { return nullptr; }
297  EIGEN_DEVICE_FUNC T *data() { return nullptr; }
298 };
299 
300 template<typename T, int Cols_, int Options_>
301 class DenseStorage<T, 0, Dynamic, Cols_, Options_> {
302  Index m_rows;
303  public:
304  EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
305  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
306  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_rows(other.m_rows) {}
307  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
308  m_rows = other.m_rows;
309  return *this;
310  }
311  EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {
312  eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
313  }
314  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
315  numext::swap(m_rows, other.m_rows);
316  }
317  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
318  EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
319  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) {
320  m_rows = rows;
321  eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
322  }
324  m_rows = rows;
325  eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
326  }
327  EIGEN_DEVICE_FUNC const T *data() const { return nullptr; }
328  EIGEN_DEVICE_FUNC T *data() { return nullptr; }
329 };
330 
331 // dynamic-size matrix with fixed-size storage
332 template<typename T, int Size, int Options_>
333 class DenseStorage<T, Size, Dynamic, Dynamic, Options_>
334 {
335  internal::plain_array<T,Size,Options_> m_data;
336  Index m_rows;
337  Index m_cols;
338  public:
339  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(), m_rows(0), m_cols(0) {}
340  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
341  : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
342  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
343  : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols) {
344  internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
345  }
346  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
347  {
348  if (this != &other)
349  {
350  m_rows = other.m_rows;
351  m_cols = other.m_cols;
352  internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
353  }
354  return *this;
355  }
356  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
357  EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
358  {
359  internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols);
360  numext::swap(m_rows,other.m_rows);
361  numext::swap(m_cols,other.m_cols);
362  }
363  EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
364  EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
365  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index cols) {
366  m_rows = rows;
367  m_cols = cols;
368  }
369  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index cols) {
370  m_rows = rows;
371  m_cols = cols;
372  }
373  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
374  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
375 };
376 
377 // dynamic-size matrix with fixed-size storage and fixed width
378 template<typename T, int Size, int Cols_, int Options_>
379 class DenseStorage<T, Size, Dynamic, Cols_, Options_>
380 {
381  internal::plain_array<T,Size,Options_> m_data;
382  Index m_rows;
383  public:
384  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_rows(0) {}
385  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
386  : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
387  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
388  : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows) {
389  internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
390  }
391 
392  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
393  {
394  if (this != &other)
395  {
396  m_rows = other.m_rows;
397  internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
398  }
399  return *this;
400  }
401  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
402  EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
403  {
404  internal::plain_array_helper::swap(m_data, m_rows * Cols_, other.m_data, other.m_rows * Cols_);
405  numext::swap(m_rows, other.m_rows);
406  }
407  EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return m_rows; }
408  EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return Cols_; }
409  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
410  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index) { m_rows = rows; }
411  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
412  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
413 };
414 
415 // dynamic-size matrix with fixed-size storage and fixed height
416 template<typename T, int Size, int Rows_, int Options_>
417 class DenseStorage<T, Size, Rows_, Dynamic, Options_>
418 {
419  internal::plain_array<T,Size,Options_> m_data;
420  Index m_cols;
421  public:
422  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_cols(0) {}
423  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
424  : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
425  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
426  : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols) {
427  internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
428  }
429  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
430  {
431  if (this != &other)
432  {
433  m_cols = other.m_cols;
434  internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
435  }
436  return *this;
437  }
438  EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
439  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
440  internal::plain_array_helper::swap(m_data, Rows_ * m_cols, other.m_data, Rows_ * other.m_cols);
441  numext::swap(m_cols, other.m_cols);
442  }
443  EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return Rows_; }
444  EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return m_cols; }
445  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
446  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index cols) { m_cols = cols; }
447  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
448  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
449 };
450 
451 // purely dynamic matrix.
452 template<typename T, int Options_>
453 class DenseStorage<T, Dynamic, Dynamic, Dynamic, Options_>
454 {
455  T *m_data;
456  Index m_rows;
457  Index m_cols;
458  public:
459  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
460  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
461  : m_data(0), m_rows(0), m_cols(0) {}
463  : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)),
464  m_rows(rows),
465  m_cols(cols) {
467  eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
468  }
469  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
470  : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(other.m_rows*other.m_cols))
471  , m_rows(other.m_rows)
472  , m_cols(other.m_cols)
473  {
475  internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
476  }
477  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
478  {
479  if (this != &other)
480  {
481  DenseStorage tmp(other);
482  this->swap(tmp);
483  }
484  return *this;
485  }
487  DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
488  : m_data(std::move(other.m_data))
489  , m_rows(std::move(other.m_rows))
490  , m_cols(std::move(other.m_cols))
491  {
492  other.m_data = nullptr;
493  other.m_rows = 0;
494  other.m_cols = 0;
495  }
497  DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
498  {
499  numext::swap(m_data, other.m_data);
500  numext::swap(m_rows, other.m_rows);
501  numext::swap(m_cols, other.m_cols);
502  return *this;
503  }
504  EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, m_rows*m_cols); }
505  EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
506  {
507  numext::swap(m_data,other.m_data);
508  numext::swap(m_rows,other.m_rows);
509  numext::swap(m_cols,other.m_cols);
510  }
511  EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
512  EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
513  void conservativeResize(Index size, Index rows, Index cols)
514  {
515  m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, m_rows*m_cols);
516  m_rows = rows;
517  m_cols = cols;
518  }
520  {
521  if(size != m_rows*m_cols)
522  {
523  internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, m_rows*m_cols);
524  if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
525  m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
526  else
527  m_data = 0;
529  }
530  m_rows = rows;
531  m_cols = cols;
532  }
533  EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
534  EIGEN_DEVICE_FUNC T *data() { return m_data; }
535 };
536 
537 // matrix with dynamic width and fixed height (so that matrix has dynamic size).
538 template<typename T, int Rows_, int Options_>
539 class DenseStorage<T, Dynamic, Rows_, Dynamic, Options_> {
540  T *m_data;
541  Index m_cols;
542  public:
543  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_cols(0) {}
544  explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
546  : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_cols(cols) {
548  eigen_internal_assert(size==rows*cols && rows==Rows_ && cols >=0);
550  }
551  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
552  : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(Rows_*other.m_cols))
553  , m_cols(other.m_cols)
554  {
556  internal::smart_copy(other.m_data, other.m_data+Rows_*m_cols, m_data);
557  }
558  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
559  {
560  if (this != &other)
561  {
562  DenseStorage tmp(other);
563  this->swap(tmp);
564  }
565  return *this;
566  }
568  DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
569  : m_data(std::move(other.m_data))
570  , m_cols(std::move(other.m_cols))
571  {
572  other.m_data = nullptr;
573  other.m_cols = 0;
574  }
576  DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
577  {
578  numext::swap(m_data, other.m_data);
579  numext::swap(m_cols, other.m_cols);
580  return *this;
581  }
582  EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Rows_*m_cols); }
583  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
584  numext::swap(m_data,other.m_data);
585  numext::swap(m_cols,other.m_cols);
586  }
587  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
588  EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
589  EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
590  {
591  m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, Rows_*m_cols);
592  m_cols = cols;
593  }
594  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols)
595  {
596  if(size != Rows_*m_cols)
597  {
598  internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Rows_*m_cols);
599  if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
600  m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
601  else
602  m_data = 0;
604  }
605  m_cols = cols;
606  }
607  EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
608  EIGEN_DEVICE_FUNC T *data() { return m_data; }
609 };
610 
611 // matrix with dynamic height and fixed width (so that matrix has dynamic size).
612 template<typename T, int Cols_, int Options_>
613 class DenseStorage<T, Dynamic, Dynamic, Cols_, Options_>
614 {
615  T *m_data;
616  Index m_rows;
617  public:
618  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0) {}
619  explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
620  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols)
621  : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_rows(rows) {
623  eigen_internal_assert(size==rows*cols && rows>=0 && cols == Cols_);
625  }
626  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
627  : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(other.m_rows*Cols_))
628  , m_rows(other.m_rows)
629  {
631  internal::smart_copy(other.m_data, other.m_data+other.m_rows*Cols_, m_data);
632  }
633  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
634  {
635  if (this != &other)
636  {
637  DenseStorage tmp(other);
638  this->swap(tmp);
639  }
640  return *this;
641  }
643  DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
644  : m_data(std::move(other.m_data))
645  , m_rows(std::move(other.m_rows))
646  {
647  other.m_data = nullptr;
648  other.m_rows = 0;
649  }
651  DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
652  {
653  numext::swap(m_data, other.m_data);
654  numext::swap(m_rows, other.m_rows);
655  return *this;
656  }
657  EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Cols_*m_rows); }
658  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
659  numext::swap(m_data,other.m_data);
660  numext::swap(m_rows,other.m_rows);
661  }
662  EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
663  EIGEN_DEVICE_FUNC static constexpr Index cols(void) { return Cols_; }
664  void conservativeResize(Index size, Index rows, Index)
665  {
666  m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, m_rows*Cols_);
667  m_rows = rows;
668  }
669  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index)
670  {
671  if(size != m_rows*Cols_)
672  {
673  internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Cols_*m_rows);
674  if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
675  m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
676  else
677  m_data = 0;
679  }
680  m_rows = rows;
681  }
682  EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
683  EIGEN_DEVICE_FUNC T *data() { return m_data; }
684 };
685 
686 } // end namespace Eigen
687 
688 #endif // EIGEN_MATRIX_H
Array< int, 3, 1 > b
#define EIGEN_ALIGN_TO_BOUNDARY(n)
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
Definition: DenseStorage.h:58
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
Definition: DenseStorage.h:18
#define eigen_internal_assert(x)
Definition: Macros.h:908
#define EIGEN_NOEXCEPT
Definition: Macros.h:1260
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:957
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define EIGEN_STACK_ALLOCATION_LIMIT
Definition: Macros.h:55
#define eigen_assert(x)
Definition: Macros.h:902
int data[]
v resize(3)
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Eigen::Triplet< double > T
constexpr void conservativeResize(Index, Index, Index)
Definition: DenseStorage.h:206
constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
Definition: DenseStorage.h:181
static constexpr Index cols(void) EIGEN_NOEXCEPT
Definition: DenseStorage.h:205
constexpr DenseStorage()
Definition: DenseStorage.h:178
constexpr DenseStorage & operator=(const DenseStorage &)=default
constexpr DenseStorage & operator=(DenseStorage &&)=default
static constexpr Index rows(void) EIGEN_NOEXCEPT
Definition: DenseStorage.h:204
constexpr void resize(Index, Index, Index)
Definition: DenseStorage.h:207
constexpr const T * data() const
Definition: DenseStorage.h:208
constexpr DenseStorage(const DenseStorage &)=default
constexpr DenseStorage(Index size, Index rows, Index cols)
Definition: DenseStorage.h:194
void swap(DenseStorage &other)
Definition: DenseStorage.h:201
internal::plain_array< T, Size, Options_ > m_data
Definition: DenseStorage.h:176
constexpr T * data()
Definition: DenseStorage.h:209
constexpr DenseStorage(DenseStorage &&)=default
@ DontAlign
Definition: Constants.h:327
T * conditional_aligned_new_auto(std::size_t size)
Definition: Memory.h:496
T * smart_move(T *start, T *end, T *target)
Definition: Memory.h:655
void smart_copy(const T *start, const T *end, T *target)
Definition: Memory.h:601
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition: Memory.h:788
constexpr void check_static_allocation_size()
Definition: DenseStorage.h:30
void swap(T &a, T &b)
Definition: Meta.h:419
: InteropHeaders
Definition: Core:139
std::array< T, N > array
Definition: EmulateArray.h:256
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82