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 (at) inria.fr> 5 // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1 (at) gmail.com> 6 // Copyright (C) 2010-2013 Hauke Heibel <hauke.heibel (at) 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