Eigen  3.4.90 (git rev a4098ac676528a83cfb73d4d26ce1b42ec05f47c)
DenseStorage.h
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
23namespace Eigen {
24
25namespace internal {
26
27struct constructor_without_unaligned_array_assert {};
28
29template<typename T, int Size>
30EIGEN_DEVICE_FUNC
31void check_static_allocation_size()
32{
33 // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
34 #if EIGEN_STACK_ALLOCATION_LIMIT
35 EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
36 #endif
37}
38
43template <typename T, int Size, int MatrixOrArrayOptions,
44 int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
45 : compute_default_alignment<T,Size>::value >
46struct plain_array
47{
48 T array[Size];
49
50 EIGEN_DEVICE_FUNC
51 plain_array()
52 {
53 check_static_allocation_size<T,Size>();
54 }
55
56 EIGEN_DEVICE_FUNC
57 plain_array(constructor_without_unaligned_array_assert)
58 {
59 check_static_allocation_size<T,Size>();
60 }
61};
62
63#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
64 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
65#elif EIGEN_COMP_GNUC
66 // GCC 4.7 is too aggressive in its optimizations and remove the alignment test based on the fact the array is declared to be aligned.
67 // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
68 // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
69 template<typename PtrType>
70 EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
71 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
72 eigen_assert((internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (sizemask)) == 0 \
73 && "this assertion is explained here: " \
74 "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
75 " **** READ THIS WEB PAGE !!! ****");
76#else
77 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
78 eigen_assert((internal::UIntPtr(array) & (sizemask)) == 0 \
79 && "this assertion is explained here: " \
80 "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
81 " **** READ THIS WEB PAGE !!! ****");
82#endif
83
84template <typename T, int Size, int MatrixOrArrayOptions>
85struct plain_array<T, Size, MatrixOrArrayOptions, 8>
86{
87 EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
88
89 EIGEN_DEVICE_FUNC
90 plain_array()
91 {
92 EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
93 check_static_allocation_size<T,Size>();
94 }
95
96 EIGEN_DEVICE_FUNC
97 plain_array(constructor_without_unaligned_array_assert)
98 {
99 check_static_allocation_size<T,Size>();
100 }
101};
102
103template <typename T, int Size, int MatrixOrArrayOptions>
104struct plain_array<T, Size, MatrixOrArrayOptions, 16>
105{
106 EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
107
108 EIGEN_DEVICE_FUNC
109 plain_array()
110 {
111 EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
112 check_static_allocation_size<T,Size>();
113 }
114
115 EIGEN_DEVICE_FUNC
116 plain_array(constructor_without_unaligned_array_assert)
117 {
118 check_static_allocation_size<T,Size>();
119 }
120};
121
122template <typename T, int Size, int MatrixOrArrayOptions>
123struct plain_array<T, Size, MatrixOrArrayOptions, 32>
124{
125 EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
126
127 EIGEN_DEVICE_FUNC
128 plain_array()
129 {
130 EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
131 check_static_allocation_size<T,Size>();
132 }
133
134 EIGEN_DEVICE_FUNC
135 plain_array(constructor_without_unaligned_array_assert)
136 {
137 check_static_allocation_size<T,Size>();
138 }
139};
140
141template <typename T, int Size, int MatrixOrArrayOptions>
142struct plain_array<T, Size, MatrixOrArrayOptions, 64>
143{
144 EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
145
146 EIGEN_DEVICE_FUNC
147 plain_array()
148 {
149 EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
150 check_static_allocation_size<T,Size>();
151 }
152
153 EIGEN_DEVICE_FUNC
154 plain_array(constructor_without_unaligned_array_assert)
155 {
156 check_static_allocation_size<T,Size>();
157 }
158};
159
160template <typename T, int MatrixOrArrayOptions, int Alignment>
161struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
162{
163 T array[1];
164 EIGEN_DEVICE_FUNC plain_array() {}
165 EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
166};
167
168struct plain_array_helper {
169 template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
171 static void copy(const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size,
172 plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) {
173 smart_copy(src.array, src.array + size, dst.array);
174 }
175
176 template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
177 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
178 static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a, const Eigen::Index a_size,
179 plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b, const Eigen::Index b_size) {
180 if (a_size < b_size) {
181 std::swap_ranges(b.array, b.array + a_size, a.array);
182 smart_move(b.array + a_size, b.array + b_size, a.array + a_size);
183 } else if (a_size > b_size) {
184 std::swap_ranges(a.array, a.array + b_size, b.array);
185 smart_move(a.array + b_size, a.array + a_size, b.array + b_size);
186 } else {
187 std::swap_ranges(a.array, a.array + a_size, b.array);
188 }
189 }
190};
191
192} // end namespace internal
193
206template<typename T, int Size, int Rows_, int Cols_, int Options_> class DenseStorage;
207
208// purely fixed-size matrix
209template<typename T, int Size, int Rows_, int Cols_, int Options_> class DenseStorage
210{
211 internal::plain_array<T,Size,Options_> m_data;
212 public:
213 EIGEN_DEVICE_FUNC DenseStorage() {
214 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
215 }
216 EIGEN_DEVICE_FUNC
217 explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
218 : m_data(internal::constructor_without_unaligned_array_assert()) {}
219#if defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
220 EIGEN_DEVICE_FUNC
221 DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
222 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
223 }
224#else
225 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) = default;
226#endif
227 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) = default;
228 EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&&) = default;
229 EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&&) = default;
230 EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
231 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
232 eigen_internal_assert(size==rows*cols && rows==Rows_ && cols==Cols_);
233 EIGEN_UNUSED_VARIABLE(size);
234 EIGEN_UNUSED_VARIABLE(rows);
235 EIGEN_UNUSED_VARIABLE(cols);
236 }
237 EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
238 numext::swap(m_data, other.m_data);
239 }
240 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
241 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
242 EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
243 EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
244 EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
245 EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
246};
247
248// null matrix
249template<typename T, int Rows_, int Cols_, int Options_> class DenseStorage<T, 0, Rows_, Cols_, Options_>
250{
251 public:
252 EIGEN_DEVICE_FUNC DenseStorage() {}
253 EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
254 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {}
255 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
256 EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
257 EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
258 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
259 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
260 EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
261 EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
262 EIGEN_DEVICE_FUNC const T *data() const { return 0; }
263 EIGEN_DEVICE_FUNC T *data() { return 0; }
264};
265
266// more specializations for null matrices; these are necessary to resolve ambiguities
267template<typename T, int Options_> class DenseStorage<T, 0, Dynamic, Dynamic, Options_>
268: public DenseStorage<T, 0, 0, 0, Options_> { };
269
270template<typename T, int Rows_, int Options_> class DenseStorage<T, 0, Rows_, Dynamic, Options_>
271: public DenseStorage<T, 0, 0, 0, Options_> { };
272
273template<typename T, int Cols_, int Options_> class DenseStorage<T, 0, Dynamic, Cols_, Options_>
274: public DenseStorage<T, 0, 0, 0, Options_> { };
275
276// dynamic-size matrix with fixed-size storage
277template<typename T, int Size, int Options_> class DenseStorage<T, Size, Dynamic, Dynamic, Options_>
278{
279 internal::plain_array<T,Size,Options_> m_data;
280 Index m_rows;
281 Index m_cols;
282 public:
283 EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
284 EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
285 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
286 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
287 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols)
288 {
289 internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
290 }
291 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
292 {
293 if (this != &other)
294 {
295 m_rows = other.m_rows;
296 m_cols = other.m_cols;
297 internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
298 }
299 return *this;
300 }
301 EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
302 EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
303 {
304 internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols);
305 numext::swap(m_rows,other.m_rows);
306 numext::swap(m_cols,other.m_cols);
307 }
308 EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
309 EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
310 EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
311 EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
312 EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
313 EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
314};
315
316// dynamic-size matrix with fixed-size storage and fixed width
317template<typename T, int Size, int Cols_, int Options_> class DenseStorage<T, Size, Dynamic, Cols_, Options_>
318{
319 internal::plain_array<T,Size,Options_> m_data;
320 Index m_rows;
321 public:
322 EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
323 EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
324 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
325 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
326 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows)
327 {
328 internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
329 }
330
331 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
332 {
333 if (this != &other)
334 {
335 m_rows = other.m_rows;
336 internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
337 }
338 return *this;
339 }
340 EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
341 EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
342 {
343 internal::plain_array_helper::swap(m_data, m_rows * Cols_, other.m_data, other.m_rows * Cols_);
344 numext::swap(m_rows, other.m_rows);
345 }
346 EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
347 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return Cols_;}
348 EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
349 EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
350 EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
351 EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
352};
353
354// dynamic-size matrix with fixed-size storage and fixed height
355template<typename T, int Size, int Rows_, int Options_> class DenseStorage<T, Size, Rows_, Dynamic, Options_>
356{
357 internal::plain_array<T,Size,Options_> m_data;
358 Index m_cols;
359 public:
360 EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
361 EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
362 : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
363 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
364 : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols)
365 {
366 internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
367 }
368 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
369 {
370 if (this != &other)
371 {
372 m_cols = other.m_cols;
373 internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
374 }
375 return *this;
376 }
377 EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
378 EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
379 internal::plain_array_helper::swap(m_data, Rows_ * m_cols, other.m_data, Rows_ * other.m_cols);
380 numext::swap(m_cols, other.m_cols);
381 }
382 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return Rows_;}
383 EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
384 EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
385 EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) { m_cols = cols; }
386 EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
387 EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
388};
389
390// purely dynamic matrix.
391template<typename T, int Options_> class DenseStorage<T, Dynamic, Dynamic, Dynamic, Options_>
392{
393 T *m_data;
394 Index m_rows;
395 Index m_cols;
396 public:
397 EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
398 EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
399 : m_data(0), m_rows(0), m_cols(0) {}
400 EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
401 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
402 {
403 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
404 eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
405 }
406 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
407 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(other.m_rows*other.m_cols))
408 , m_rows(other.m_rows)
409 , m_cols(other.m_cols)
410 {
411 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
412 internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
413 }
414 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
415 {
416 if (this != &other)
417 {
418 DenseStorage tmp(other);
419 this->swap(tmp);
420 }
421 return *this;
422 }
423 EIGEN_DEVICE_FUNC
424 DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
425 : m_data(std::move(other.m_data))
426 , m_rows(std::move(other.m_rows))
427 , m_cols(std::move(other.m_cols))
428 {
429 other.m_data = nullptr;
430 other.m_rows = 0;
431 other.m_cols = 0;
432 }
433 EIGEN_DEVICE_FUNC
434 DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
435 {
436 numext::swap(m_data, other.m_data);
437 numext::swap(m_rows, other.m_rows);
438 numext::swap(m_cols, other.m_cols);
439 return *this;
440 }
441 EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, m_rows*m_cols); }
442 EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
443 {
444 numext::swap(m_data,other.m_data);
445 numext::swap(m_rows,other.m_rows);
446 numext::swap(m_cols,other.m_cols);
447 }
448 EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
449 EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
450 void conservativeResize(Index size, Index rows, Index cols)
451 {
452 m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, m_rows*m_cols);
453 m_rows = rows;
454 m_cols = cols;
455 }
456 EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols)
457 {
458 if(size != m_rows*m_cols)
459 {
460 internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, m_rows*m_cols);
461 if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
462 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
463 else
464 m_data = 0;
465 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
466 }
467 m_rows = rows;
468 m_cols = cols;
469 }
470 EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
471 EIGEN_DEVICE_FUNC T *data() { return m_data; }
472};
473
474// matrix with dynamic width and fixed height (so that matrix has dynamic size).
475template<typename T, int Rows_, int Options_> class DenseStorage<T, Dynamic, Rows_, Dynamic, Options_>
476{
477 T *m_data;
478 Index m_cols;
479 public:
480 EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {}
481 explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
482 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)
483 {
484 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
485 eigen_internal_assert(size==rows*cols && rows==Rows_ && cols >=0);
486 EIGEN_UNUSED_VARIABLE(rows);
487 }
488 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
489 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(Rows_*other.m_cols))
490 , m_cols(other.m_cols)
491 {
492 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*Rows_)
493 internal::smart_copy(other.m_data, other.m_data+Rows_*m_cols, m_data);
494 }
495 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
496 {
497 if (this != &other)
498 {
499 DenseStorage tmp(other);
500 this->swap(tmp);
501 }
502 return *this;
503 }
504 EIGEN_DEVICE_FUNC
505 DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
506 : m_data(std::move(other.m_data))
507 , m_cols(std::move(other.m_cols))
508 {
509 other.m_data = nullptr;
510 other.m_cols = 0;
511 }
512 EIGEN_DEVICE_FUNC
513 DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
514 {
515 numext::swap(m_data, other.m_data);
516 numext::swap(m_cols, other.m_cols);
517 return *this;
518 }
519 EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Rows_*m_cols); }
520 EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
521 numext::swap(m_data,other.m_data);
522 numext::swap(m_cols,other.m_cols);
523 }
524 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
525 EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
526 EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
527 {
528 m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, Rows_*m_cols);
529 m_cols = cols;
530 }
531 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols)
532 {
533 if(size != Rows_*m_cols)
534 {
535 internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Rows_*m_cols);
536 if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
537 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
538 else
539 m_data = 0;
540 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
541 }
542 m_cols = cols;
543 }
544 EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
545 EIGEN_DEVICE_FUNC T *data() { return m_data; }
546};
547
548// matrix with dynamic height and fixed width (so that matrix has dynamic size).
549template<typename T, int Cols_, int Options_> class DenseStorage<T, Dynamic, Dynamic, Cols_, Options_>
550{
551 T *m_data;
552 Index m_rows;
553 public:
554 EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {}
555 explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
556 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)
557 {
558 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
559 eigen_internal_assert(size==rows*cols && rows>=0 && cols == Cols_);
560 EIGEN_UNUSED_VARIABLE(cols);
561 }
562 EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
563 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(other.m_rows*Cols_))
564 , m_rows(other.m_rows)
565 {
566 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*Cols_)
567 internal::smart_copy(other.m_data, other.m_data+other.m_rows*Cols_, m_data);
568 }
569 EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
570 {
571 if (this != &other)
572 {
573 DenseStorage tmp(other);
574 this->swap(tmp);
575 }
576 return *this;
577 }
578 EIGEN_DEVICE_FUNC
579 DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
580 : m_data(std::move(other.m_data))
581 , m_rows(std::move(other.m_rows))
582 {
583 other.m_data = nullptr;
584 other.m_rows = 0;
585 }
586 EIGEN_DEVICE_FUNC
587 DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
588 {
589 numext::swap(m_data, other.m_data);
590 numext::swap(m_rows, other.m_rows);
591 return *this;
592 }
593 EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Cols_*m_rows); }
594 EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
595 numext::swap(m_data,other.m_data);
596 numext::swap(m_rows,other.m_rows);
597 }
598 EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
599 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) {return Cols_;}
600 void conservativeResize(Index size, Index rows, Index)
601 {
602 m_data = internal::conditional_aligned_realloc_new_auto<T,(Options_&DontAlign)==0>(m_data, size, m_rows*Cols_);
603 m_rows = rows;
604 }
605 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index)
606 {
607 if(size != m_rows*Cols_)
608 {
609 internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, Cols_*m_rows);
610 if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
611 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
612 else
613 m_data = 0;
614 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
615 }
616 m_rows = rows;
617 }
618 EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
619 EIGEN_DEVICE_FUNC T *data() { return m_data; }
620};
621
622} // end namespace Eigen
623
624#endif // EIGEN_MATRIX_H
@ DontAlign
Definition: Constants.h:327
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59