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 alignment 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 | struct plain_array_helper { |
167 | template<typename T, int Size, int MatrixOrArrayOptions, int Alignment> |
168 | EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE |
169 | static void copy(const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size, |
170 | plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) { |
171 | smart_copy(src.array, src.array + size, dst.array); |
172 | } |
173 | |
174 | template<typename T, int Size, int MatrixOrArrayOptions, int Alignment> |
175 | EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE |
176 | static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a, const Eigen::Index a_size, |
177 | plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b, const Eigen::Index b_size) { |
178 | if (a_size < b_size) { |
179 | std::swap_ranges(b.array, b.array + a_size, a.array); |
180 | smart_move(b.array + a_size, b.array + b_size, a.array + a_size); |
181 | } else if (a_size > b_size) { |
182 | std::swap_ranges(a.array, a.array + b_size, b.array); |
183 | smart_move(a.array + b_size, a.array + a_size, b.array + b_size); |
184 | } else { |
185 | std::swap_ranges(a.array, a.array + a_size, b.array); |
186 | } |
187 | } |
188 | }; |
189 | |
190 | } // end namespace internal |
191 | |
192 | /** \internal |
193 | * |
194 | * \class DenseStorage |
195 | * \ingroup Core_Module |
196 | * |
197 | * \brief Stores the data of a matrix |
198 | * |
199 | * This class stores the data of fixed-size, dynamic-size or mixed matrices |
200 | * in a way as compact as possible. |
201 | * |
202 | * \sa Matrix |
203 | */ |
204 | template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage; |
205 | |
206 | // purely fixed-size matrix |
207 | template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage |
208 | { |
209 | internal::plain_array<T,Size,_Options> m_data; |
210 | public: |
211 | EIGEN_DEVICE_FUNC DenseStorage() { |
212 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) |
213 | } |
214 | EIGEN_DEVICE_FUNC |
215 | explicit DenseStorage(internal::constructor_without_unaligned_array_assert) |
216 | : m_data(internal::constructor_without_unaligned_array_assert()) {} |
217 | #if !EIGEN_HAS_CXX11 || defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN) |
218 | EIGEN_DEVICE_FUNC |
219 | DenseStorage(const DenseStorage& other) : m_data(other.m_data) { |
220 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) |
221 | } |
222 | #else |
223 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) = default; |
224 | #endif |
225 | #if !EIGEN_HAS_CXX11 |
226 | EIGEN_DEVICE_FUNC |
227 | DenseStorage& operator=(const DenseStorage& other) |
228 | { |
229 | if (this != &other) m_data = other.m_data; |
230 | return *this; |
231 | } |
232 | #else |
233 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) = default; |
234 | #endif |
235 | #if EIGEN_HAS_RVALUE_REFERENCES |
236 | #if !EIGEN_HAS_CXX11 |
237 | EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT |
238 | : m_data(std::move(other.m_data)) |
239 | { |
240 | } |
241 | EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT |
242 | { |
243 | if (this != &other) |
244 | m_data = std::move(other.m_data); |
245 | return *this; |
246 | } |
247 | #else |
248 | EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&&) = default; |
249 | EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&&) = default; |
250 | #endif |
251 | #endif |
252 | EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) { |
253 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
254 | eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols); |
255 | EIGEN_UNUSED_VARIABLE(size); |
256 | EIGEN_UNUSED_VARIABLE(rows); |
257 | EIGEN_UNUSED_VARIABLE(cols); |
258 | } |
259 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { |
260 | numext::swap(m_data, other.m_data); |
261 | } |
262 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;} |
263 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;} |
264 | EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {} |
265 | EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {} |
266 | EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } |
267 | EIGEN_DEVICE_FUNC T *data() { return m_data.array; } |
268 | }; |
269 | |
270 | // null matrix |
271 | template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options> |
272 | { |
273 | public: |
274 | EIGEN_DEVICE_FUNC DenseStorage() {} |
275 | EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {} |
276 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {} |
277 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; } |
278 | EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {} |
279 | EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {} |
280 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;} |
281 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;} |
282 | EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {} |
283 | EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {} |
284 | EIGEN_DEVICE_FUNC const T *data() const { return 0; } |
285 | EIGEN_DEVICE_FUNC T *data() { return 0; } |
286 | }; |
287 | |
288 | // more specializations for null matrices; these are necessary to resolve ambiguities |
289 | template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options> |
290 | : public DenseStorage<T, 0, 0, 0, _Options> { }; |
291 | |
292 | template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options> |
293 | : public DenseStorage<T, 0, 0, 0, _Options> { }; |
294 | |
295 | template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options> |
296 | : public DenseStorage<T, 0, 0, 0, _Options> { }; |
297 | |
298 | // dynamic-size matrix with fixed-size storage |
299 | template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options> |
300 | { |
301 | internal::plain_array<T,Size,_Options> m_data; |
302 | Index m_rows; |
303 | Index m_cols; |
304 | public: |
305 | EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {} |
306 | EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) |
307 | : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} |
308 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
309 | : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols) |
310 | { |
311 | internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data); |
312 | } |
313 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
314 | { |
315 | if (this != &other) |
316 | { |
317 | m_rows = other.m_rows; |
318 | m_cols = other.m_cols; |
319 | internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data); |
320 | } |
321 | return *this; |
322 | } |
323 | EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {} |
324 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) |
325 | { |
326 | internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols); |
327 | numext::swap(m_rows,other.m_rows); |
328 | numext::swap(m_cols,other.m_cols); |
329 | } |
330 | EIGEN_DEVICE_FUNC Index rows() const {return m_rows;} |
331 | EIGEN_DEVICE_FUNC Index cols() const {return m_cols;} |
332 | EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; } |
333 | EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; } |
334 | EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } |
335 | EIGEN_DEVICE_FUNC T *data() { return m_data.array; } |
336 | }; |
337 | |
338 | // dynamic-size matrix with fixed-size storage and fixed width |
339 | template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options> |
340 | { |
341 | internal::plain_array<T,Size,_Options> m_data; |
342 | Index m_rows; |
343 | public: |
344 | EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {} |
345 | EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) |
346 | : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} |
347 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
348 | : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows) |
349 | { |
350 | internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data); |
351 | } |
352 | |
353 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
354 | { |
355 | if (this != &other) |
356 | { |
357 | m_rows = other.m_rows; |
358 | internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data); |
359 | } |
360 | return *this; |
361 | } |
362 | EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {} |
363 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) |
364 | { |
365 | internal::plain_array_helper::swap(m_data, m_rows * _Cols, other.m_data, other.m_rows * _Cols); |
366 | numext::swap(m_rows, other.m_rows); |
367 | } |
368 | EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;} |
369 | EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return _Cols;} |
370 | EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; } |
371 | EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; } |
372 | EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } |
373 | EIGEN_DEVICE_FUNC T *data() { return m_data.array; } |
374 | }; |
375 | |
376 | // dynamic-size matrix with fixed-size storage and fixed height |
377 | template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options> |
378 | { |
379 | internal::plain_array<T,Size,_Options> m_data; |
380 | Index m_cols; |
381 | public: |
382 | EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {} |
383 | EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) |
384 | : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} |
385 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
386 | : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols) |
387 | { |
388 | internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data); |
389 | } |
390 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
391 | { |
392 | if (this != &other) |
393 | { |
394 | m_cols = other.m_cols; |
395 | internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data); |
396 | } |
397 | return *this; |
398 | } |
399 | EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {} |
400 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { |
401 | internal::plain_array_helper::swap(m_data, _Rows * m_cols, other.m_data, _Rows * other.m_cols); |
402 | numext::swap(m_cols, other.m_cols); |
403 | } |
404 | EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return _Rows;} |
405 | EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;} |
406 | EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) { m_cols = cols; } |
407 | EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) { m_cols = cols; } |
408 | EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } |
409 | EIGEN_DEVICE_FUNC T *data() { return m_data.array; } |
410 | }; |
411 | |
412 | // purely dynamic matrix. |
413 | template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options> |
414 | { |
415 | T *m_data; |
416 | Index m_rows; |
417 | Index m_cols; |
418 | public: |
419 | EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} |
420 | EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) |
421 | : m_data(0), m_rows(0), m_cols(0) {} |
422 | EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) |
423 | : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols) |
424 | { |
425 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
426 | eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0); |
427 | } |
428 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
429 | : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*other.m_cols)) |
430 | , m_rows(other.m_rows) |
431 | , m_cols(other.m_cols) |
432 | { |
433 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols) |
434 | internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data); |
435 | } |
436 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
437 | { |
438 | if (this != &other) |
439 | { |
440 | DenseStorage tmp(other); |
441 | this->swap(tmp); |
442 | } |
443 | return *this; |
444 | } |
445 | #if EIGEN_HAS_RVALUE_REFERENCES |
446 | EIGEN_DEVICE_FUNC |
447 | DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT |
448 | : m_data(std::move(other.m_data)) |
449 | , m_rows(std::move(other.m_rows)) |
450 | , m_cols(std::move(other.m_cols)) |
451 | { |
452 | other.m_data = nullptr; |
453 | other.m_rows = 0; |
454 | other.m_cols = 0; |
455 | } |
456 | EIGEN_DEVICE_FUNC |
457 | DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT |
458 | { |
459 | numext::swap(m_data, other.m_data); |
460 | numext::swap(m_rows, other.m_rows); |
461 | numext::swap(m_cols, other.m_cols); |
462 | return *this; |
463 | } |
464 | #endif |
465 | EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); } |
466 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) |
467 | { |
468 | numext::swap(m_data,other.m_data); |
469 | numext::swap(m_rows,other.m_rows); |
470 | numext::swap(m_cols,other.m_cols); |
471 | } |
472 | EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;} |
473 | EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;} |
474 | void conservativeResize(Index size, Index rows, Index cols) |
475 | { |
476 | m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols); |
477 | m_rows = rows; |
478 | m_cols = cols; |
479 | } |
480 | EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols) |
481 | { |
482 | if(size != m_rows*m_cols) |
483 | { |
484 | internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); |
485 | if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative |
486 | m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); |
487 | else |
488 | m_data = 0; |
489 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
490 | } |
491 | m_rows = rows; |
492 | m_cols = cols; |
493 | } |
494 | EIGEN_DEVICE_FUNC const T *data() const { return m_data; } |
495 | EIGEN_DEVICE_FUNC T *data() { return m_data; } |
496 | }; |
497 | |
498 | // matrix with dynamic width and fixed height (so that matrix has dynamic size). |
499 | template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options> |
500 | { |
501 | T *m_data; |
502 | Index m_cols; |
503 | public: |
504 | EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {} |
505 | explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} |
506 | 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) |
507 | { |
508 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
509 | eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0); |
510 | EIGEN_UNUSED_VARIABLE(rows); |
511 | } |
512 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
513 | : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols)) |
514 | , m_cols(other.m_cols) |
515 | { |
516 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows) |
517 | internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data); |
518 | } |
519 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
520 | { |
521 | if (this != &other) |
522 | { |
523 | DenseStorage tmp(other); |
524 | this->swap(tmp); |
525 | } |
526 | return *this; |
527 | } |
528 | #if EIGEN_HAS_RVALUE_REFERENCES |
529 | EIGEN_DEVICE_FUNC |
530 | DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT |
531 | : m_data(std::move(other.m_data)) |
532 | , m_cols(std::move(other.m_cols)) |
533 | { |
534 | other.m_data = nullptr; |
535 | other.m_cols = 0; |
536 | } |
537 | EIGEN_DEVICE_FUNC |
538 | DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT |
539 | { |
540 | numext::swap(m_data, other.m_data); |
541 | numext::swap(m_cols, other.m_cols); |
542 | return *this; |
543 | } |
544 | #endif |
545 | EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); } |
546 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { |
547 | numext::swap(m_data,other.m_data); |
548 | numext::swap(m_cols,other.m_cols); |
549 | } |
550 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;} |
551 | EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;} |
552 | EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols) |
553 | { |
554 | m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols); |
555 | m_cols = cols; |
556 | } |
557 | EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols) |
558 | { |
559 | if(size != _Rows*m_cols) |
560 | { |
561 | internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); |
562 | if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative |
563 | m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); |
564 | else |
565 | m_data = 0; |
566 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
567 | } |
568 | m_cols = cols; |
569 | } |
570 | EIGEN_DEVICE_FUNC const T *data() const { return m_data; } |
571 | EIGEN_DEVICE_FUNC T *data() { return m_data; } |
572 | }; |
573 | |
574 | // matrix with dynamic height and fixed width (so that matrix has dynamic size). |
575 | template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options> |
576 | { |
577 | T *m_data; |
578 | Index m_rows; |
579 | public: |
580 | EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {} |
581 | explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} |
582 | 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) |
583 | { |
584 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
585 | eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols); |
586 | EIGEN_UNUSED_VARIABLE(cols); |
587 | } |
588 | EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) |
589 | : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols)) |
590 | , m_rows(other.m_rows) |
591 | { |
592 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols) |
593 | internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data); |
594 | } |
595 | EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) |
596 | { |
597 | if (this != &other) |
598 | { |
599 | DenseStorage tmp(other); |
600 | this->swap(tmp); |
601 | } |
602 | return *this; |
603 | } |
604 | #if EIGEN_HAS_RVALUE_REFERENCES |
605 | EIGEN_DEVICE_FUNC |
606 | DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT |
607 | : m_data(std::move(other.m_data)) |
608 | , m_rows(std::move(other.m_rows)) |
609 | { |
610 | other.m_data = nullptr; |
611 | other.m_rows = 0; |
612 | } |
613 | EIGEN_DEVICE_FUNC |
614 | DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT |
615 | { |
616 | numext::swap(m_data, other.m_data); |
617 | numext::swap(m_rows, other.m_rows); |
618 | return *this; |
619 | } |
620 | #endif |
621 | EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); } |
622 | EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { |
623 | numext::swap(m_data,other.m_data); |
624 | numext::swap(m_rows,other.m_rows); |
625 | } |
626 | EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;} |
627 | EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) {return _Cols;} |
628 | void conservativeResize(Index size, Index rows, Index) |
629 | { |
630 | m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols); |
631 | m_rows = rows; |
632 | } |
633 | EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index) |
634 | { |
635 | if(size != m_rows*_Cols) |
636 | { |
637 | internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); |
638 | if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative |
639 | m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); |
640 | else |
641 | m_data = 0; |
642 | EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) |
643 | } |
644 | m_rows = rows; |
645 | } |
646 | EIGEN_DEVICE_FUNC const T *data() const { return m_data; } |
647 | EIGEN_DEVICE_FUNC T *data() { return m_data; } |
648 | }; |
649 | |
650 | } // end namespace Eigen |
651 | |
652 | #endif // EIGEN_MATRIX_H |
653 | |