Branch data Line data Source code
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 : 95078 : 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 : 95078 : }
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 : 66871 : plain_array()
50 : : {
51 : 66871 : check_static_allocation_size<T,Size>();
52 : 66871 : }
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 : 28207 : 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 : 28207 : plain_array()
108 : : {
109 : 56414 : EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
110 : 28207 : check_static_allocation_size<T,Size>();
111 : 28207 : }
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 : 95078 : EIGEN_DEVICE_FUNC DenseStorage() {
212 : : EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
213 : 95078 : }
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 : 502537 : EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
263 : 491586 : EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
264 : : EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
265 : 52670 : EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
266 : 429814 : EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
267 : 108019 : 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
|