Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DenseStorage.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> 00007 // 00008 // This Source Code Form is subject to the terms of the Mozilla 00009 // Public License v. 2.0. If a copy of the MPL was not distributed 00010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00011 00012 #ifndef EIGEN_MATRIXSTORAGE_H 00013 #define EIGEN_MATRIXSTORAGE_H 00014 00015 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 00016 #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN; 00017 #else 00018 #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN 00019 #endif 00020 00021 namespace Eigen { 00022 00023 namespace internal { 00024 00025 struct constructor_without_unaligned_array_assert {}; 00026 00027 template<typename T, int Size> void check_static_allocation_size() 00028 { 00029 // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit 00030 #if EIGEN_STACK_ALLOCATION_LIMIT 00031 EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); 00032 #endif 00033 } 00034 00035 /** \internal 00036 * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: 00037 * to 16 bytes boundary if the total size is a multiple of 16 bytes. 00038 */ 00039 template <typename T, int Size, int MatrixOrArrayOptions, 00040 int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0 00041 : (((Size*sizeof(T))%16)==0) ? 16 00042 : 0 > 00043 struct plain_array 00044 { 00045 T array[Size]; 00046 00047 plain_array() 00048 { 00049 check_static_allocation_size<T,Size>(); 00050 } 00051 00052 plain_array(constructor_without_unaligned_array_assert) 00053 { 00054 check_static_allocation_size<T,Size>(); 00055 } 00056 }; 00057 00058 #if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) 00059 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) 00060 #elif EIGEN_GNUC_AT_LEAST(4,7) 00061 // 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. 00062 // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 00063 // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined: 00064 template<typename PtrType> 00065 EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } 00066 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ 00067 eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \ 00068 && "this assertion is explained here: " \ 00069 "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ 00070 " **** READ THIS WEB PAGE !!! ****"); 00071 #else 00072 #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ 00073 eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \ 00074 && "this assertion is explained here: " \ 00075 "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ 00076 " **** READ THIS WEB PAGE !!! ****"); 00077 #endif 00078 00079 template <typename T, int Size, int MatrixOrArrayOptions> 00080 struct plain_array<T, Size, MatrixOrArrayOptions, 16> 00081 { 00082 EIGEN_USER_ALIGN16 T array[Size]; 00083 00084 plain_array() 00085 { 00086 EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf); 00087 check_static_allocation_size<T,Size>(); 00088 } 00089 00090 plain_array(constructor_without_unaligned_array_assert) 00091 { 00092 check_static_allocation_size<T,Size>(); 00093 } 00094 }; 00095 00096 template <typename T, int MatrixOrArrayOptions, int Alignment> 00097 struct plain_array<T, 0, MatrixOrArrayOptions, Alignment> 00098 { 00099 EIGEN_USER_ALIGN16 T array[1]; 00100 plain_array() {} 00101 plain_array(constructor_without_unaligned_array_assert) {} 00102 }; 00103 00104 } // end namespace internal 00105 00106 /** \internal 00107 * 00108 * \class DenseStorage 00109 * \ingroup Core_Module 00110 * 00111 * \brief Stores the data of a matrix 00112 * 00113 * This class stores the data of fixed-size, dynamic-size or mixed matrices 00114 * in a way as compact as possible. 00115 * 00116 * \sa Matrix 00117 */ 00118 template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage; 00119 00120 // purely fixed-size matrix 00121 template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage 00122 { 00123 internal::plain_array<T,Size,_Options> m_data; 00124 public: 00125 DenseStorage() {} 00126 DenseStorage(internal::constructor_without_unaligned_array_assert) 00127 : m_data(internal::constructor_without_unaligned_array_assert()) {} 00128 DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} 00129 DenseStorage& operator=(const DenseStorage& other) 00130 { 00131 if (this != &other) m_data = other.m_data; 00132 return *this; 00133 } 00134 DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} 00135 void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } 00136 static DenseIndex rows(void) {return _Rows;} 00137 static DenseIndex cols(void) {return _Cols;} 00138 void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} 00139 void resize(DenseIndex,DenseIndex,DenseIndex) {} 00140 const T *data() const { return m_data.array; } 00141 T *data() { return m_data.array; } 00142 }; 00143 00144 // null matrix 00145 template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options> 00146 { 00147 public: 00148 DenseStorage() {} 00149 DenseStorage(internal::constructor_without_unaligned_array_assert) {} 00150 DenseStorage(const DenseStorage&) {} 00151 DenseStorage& operator=(const DenseStorage&) { return *this; } 00152 DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} 00153 void swap(DenseStorage& ) {} 00154 static DenseIndex rows(void) {return _Rows;} 00155 static DenseIndex cols(void) {return _Cols;} 00156 void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} 00157 void resize(DenseIndex,DenseIndex,DenseIndex) {} 00158 const T *data() const { return 0; } 00159 T *data() { return 0; } 00160 }; 00161 00162 // more specializations for null matrices; these are necessary to resolve ambiguities 00163 template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options> 00164 : public DenseStorage<T, 0, 0, 0, _Options> { }; 00165 00166 template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options> 00167 : public DenseStorage<T, 0, 0, 0, _Options> { }; 00168 00169 template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options> 00170 : public DenseStorage<T, 0, 0, 0, _Options> { }; 00171 00172 // dynamic-size matrix with fixed-size storage 00173 template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options> 00174 { 00175 internal::plain_array<T,Size,_Options> m_data; 00176 DenseIndex m_rows; 00177 DenseIndex m_cols; 00178 public: 00179 DenseStorage() : m_rows(0), m_cols(0) {} 00180 DenseStorage(internal::constructor_without_unaligned_array_assert) 00181 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} 00182 DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {} 00183 DenseStorage& operator=(const DenseStorage& other) 00184 { 00185 if (this != &other) 00186 { 00187 m_data = other.m_data; 00188 m_rows = other.m_rows; 00189 m_cols = other.m_cols; 00190 } 00191 return *this; 00192 } 00193 DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {} 00194 void swap(DenseStorage& other) 00195 { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } 00196 DenseIndex rows() const {return m_rows;} 00197 DenseIndex cols() const {return m_cols;} 00198 void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } 00199 void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; } 00200 const T *data() const { return m_data.array; } 00201 T *data() { return m_data.array; } 00202 }; 00203 00204 // dynamic-size matrix with fixed-size storage and fixed width 00205 template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options> 00206 { 00207 internal::plain_array<T,Size,_Options> m_data; 00208 DenseIndex m_rows; 00209 public: 00210 DenseStorage() : m_rows(0) {} 00211 DenseStorage(internal::constructor_without_unaligned_array_assert) 00212 : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} 00213 DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {} 00214 DenseStorage& operator=(const DenseStorage& other) 00215 { 00216 if (this != &other) 00217 { 00218 m_data = other.m_data; 00219 m_rows = other.m_rows; 00220 } 00221 return *this; 00222 } 00223 DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} 00224 void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } 00225 DenseIndex rows(void) const {return m_rows;} 00226 DenseIndex cols(void) const {return _Cols;} 00227 void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } 00228 void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } 00229 const T *data() const { return m_data.array; } 00230 T *data() { return m_data.array; } 00231 }; 00232 00233 // dynamic-size matrix with fixed-size storage and fixed height 00234 template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options> 00235 { 00236 internal::plain_array<T,Size,_Options> m_data; 00237 DenseIndex m_cols; 00238 public: 00239 DenseStorage() : m_cols(0) {} 00240 DenseStorage(internal::constructor_without_unaligned_array_assert) 00241 : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} 00242 DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {} 00243 DenseStorage& operator=(const DenseStorage& other) 00244 { 00245 if (this != &other) 00246 { 00247 m_data = other.m_data; 00248 m_cols = other.m_cols; 00249 } 00250 return *this; 00251 } 00252 DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} 00253 void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } 00254 DenseIndex rows(void) const {return _Rows;} 00255 DenseIndex cols(void) const {return m_cols;} 00256 void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } 00257 void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } 00258 const T *data() const { return m_data.array; } 00259 T *data() { return m_data.array; } 00260 }; 00261 00262 // purely dynamic matrix. 00263 template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options> 00264 { 00265 T *m_data; 00266 DenseIndex m_rows; 00267 DenseIndex m_cols; 00268 public: 00269 DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} 00270 DenseStorage(internal::constructor_without_unaligned_array_assert) 00271 : m_data(0), m_rows(0), m_cols(0) {} 00272 DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) 00273 : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols) 00274 { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } 00275 #ifdef EIGEN_HAVE_RVALUE_REFERENCES 00276 DenseStorage(DenseStorage&& other) 00277 : m_data(std::move(other.m_data)) 00278 , m_rows(std::move(other.m_rows)) 00279 , m_cols(std::move(other.m_cols)) 00280 { 00281 other.m_data = nullptr; 00282 } 00283 DenseStorage& operator=(DenseStorage&& other) 00284 { 00285 using std::swap; 00286 swap(m_data, other.m_data); 00287 swap(m_rows, other.m_rows); 00288 swap(m_cols, other.m_cols); 00289 return *this; 00290 } 00291 #endif 00292 ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); } 00293 void swap(DenseStorage& other) 00294 { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } 00295 DenseIndex rows(void) const {return m_rows;} 00296 DenseIndex cols(void) const {return m_cols;} 00297 void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) 00298 { 00299 m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols); 00300 m_rows = nbRows; 00301 m_cols = nbCols; 00302 } 00303 void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) 00304 { 00305 if(size != m_rows*m_cols) 00306 { 00307 internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); 00308 if (size) 00309 m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); 00310 else 00311 m_data = 0; 00312 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN 00313 } 00314 m_rows = nbRows; 00315 m_cols = nbCols; 00316 } 00317 const T *data() const { return m_data; } 00318 T *data() { return m_data; } 00319 private: 00320 DenseStorage(const DenseStorage&); 00321 DenseStorage& operator=(const DenseStorage&); 00322 }; 00323 00324 // matrix with dynamic width and fixed height (so that matrix has dynamic size). 00325 template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options> 00326 { 00327 T *m_data; 00328 DenseIndex m_cols; 00329 public: 00330 DenseStorage() : m_data(0), m_cols(0) {} 00331 DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} 00332 DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols) 00333 { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } 00334 #ifdef EIGEN_HAVE_RVALUE_REFERENCES 00335 DenseStorage(DenseStorage&& other) 00336 : m_data(std::move(other.m_data)) 00337 , m_cols(std::move(other.m_cols)) 00338 { 00339 other.m_data = nullptr; 00340 } 00341 DenseStorage& operator=(DenseStorage&& other) 00342 { 00343 using std::swap; 00344 swap(m_data, other.m_data); 00345 swap(m_cols, other.m_cols); 00346 return *this; 00347 } 00348 #endif 00349 ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); } 00350 void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } 00351 static DenseIndex rows(void) {return _Rows;} 00352 DenseIndex cols(void) const {return m_cols;} 00353 void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) 00354 { 00355 m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols); 00356 m_cols = nbCols; 00357 } 00358 EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols) 00359 { 00360 if(size != _Rows*m_cols) 00361 { 00362 internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); 00363 if (size) 00364 m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); 00365 else 00366 m_data = 0; 00367 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN 00368 } 00369 m_cols = nbCols; 00370 } 00371 const T *data() const { return m_data; } 00372 T *data() { return m_data; } 00373 private: 00374 DenseStorage(const DenseStorage&); 00375 DenseStorage& operator=(const DenseStorage&); 00376 }; 00377 00378 // matrix with dynamic height and fixed width (so that matrix has dynamic size). 00379 template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options> 00380 { 00381 T *m_data; 00382 DenseIndex m_rows; 00383 public: 00384 DenseStorage() : m_data(0), m_rows(0) {} 00385 DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} 00386 DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows) 00387 { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } 00388 #ifdef EIGEN_HAVE_RVALUE_REFERENCES 00389 DenseStorage(DenseStorage&& other) 00390 : m_data(std::move(other.m_data)) 00391 , m_rows(std::move(other.m_rows)) 00392 { 00393 other.m_data = nullptr; 00394 } 00395 DenseStorage& operator=(DenseStorage&& other) 00396 { 00397 using std::swap; 00398 swap(m_data, other.m_data); 00399 swap(m_rows, other.m_rows); 00400 return *this; 00401 } 00402 #endif 00403 ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); } 00404 void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } 00405 DenseIndex rows(void) const {return m_rows;} 00406 static DenseIndex cols(void) {return _Cols;} 00407 void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) 00408 { 00409 m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols); 00410 m_rows = nbRows; 00411 } 00412 EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex) 00413 { 00414 if(size != m_rows*_Cols) 00415 { 00416 internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); 00417 if (size) 00418 m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); 00419 else 00420 m_data = 0; 00421 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN 00422 } 00423 m_rows = nbRows; 00424 } 00425 const T *data() const { return m_data; } 00426 T *data() { return m_data; } 00427 private: 00428 DenseStorage(const DenseStorage&); 00429 DenseStorage& operator=(const DenseStorage&); 00430 }; 00431 00432 } // end namespace Eigen 00433 00434 #endif // EIGEN_MATRIX_H
Generated on Thu Nov 17 2022 22:01:28 by
1.7.2