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