DenseStorage.h (25360B)
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