DenseStorage.h
Go to the documentation of this file.
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 // Eigen is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Lesser General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 3 of the License, or (at your option) any later version.
00012 //
00013 // Alternatively, you can redistribute it and/or
00014 // modify it under the terms of the GNU General Public License as
00015 // published by the Free Software Foundation; either version 2 of
00016 // the License, or (at your option) any later version.
00017 //
00018 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00019 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00020 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00021 // GNU General Public License for more details.
00022 //
00023 // You should have received a copy of the GNU Lesser General Public
00024 // License and a copy of the GNU General Public License along with
00025 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 #ifndef EIGEN_MATRIXSTORAGE_H
00028 #define EIGEN_MATRIXSTORAGE_H
00029 
00030 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
00031   #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
00032 #else
00033   #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
00034 #endif
00035 
00036 namespace Eigen {
00037 
00038 namespace internal {
00039 
00040 struct constructor_without_unaligned_array_assert {};
00041 
00046 template <typename T, int Size, int MatrixOrArrayOptions,
00047           int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
00048                         : (((Size*sizeof(T))%16)==0) ? 16
00049                         : 0 >
00050 struct plain_array
00051 {
00052   T array[Size];
00053   plain_array() {}
00054   plain_array(constructor_without_unaligned_array_assert) {}
00055 };
00056 
00057 #ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
00058   #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
00059 #else
00060   #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
00061     eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
00062               && "this assertion is explained here: " \
00063               "http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \
00064               " **** READ THIS WEB PAGE !!! ****");
00065 #endif
00066 
00067 template <typename T, int Size, int MatrixOrArrayOptions>
00068 struct plain_array<T, Size, MatrixOrArrayOptions, 16>
00069 {
00070   EIGEN_USER_ALIGN16 T array[Size];
00071   plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
00072   plain_array(constructor_without_unaligned_array_assert) {}
00073 };
00074 
00075 template <typename T, int MatrixOrArrayOptions, int Alignment>
00076 struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
00077 {
00078   EIGEN_USER_ALIGN16 T array[1];
00079   plain_array() {}
00080   plain_array(constructor_without_unaligned_array_assert) {}
00081 };
00082 
00083 } // end namespace internal
00084 
00097 template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage;
00098 
00099 // purely fixed-size matrix
00100 template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage
00101 {
00102     internal::plain_array<T,Size,_Options> m_data;
00103   public:
00104     inline explicit DenseStorage() {}
00105     inline DenseStorage(internal::constructor_without_unaligned_array_assert)
00106       : m_data(internal::constructor_without_unaligned_array_assert()) {}
00107     inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
00108     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
00109     static inline DenseIndex rows(void) {return _Rows;}
00110     static inline DenseIndex cols(void) {return _Cols;}
00111     inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
00112     inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
00113     inline const T *data() const { return m_data.array; }
00114     inline T *data() { return m_data.array; }
00115 };
00116 
00117 // null matrix
00118 template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
00119 {
00120   public:
00121     inline explicit DenseStorage() {}
00122     inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
00123     inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
00124     inline void swap(DenseStorage& ) {}
00125     static inline DenseIndex rows(void) {return _Rows;}
00126     static inline DenseIndex cols(void) {return _Cols;}
00127     inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
00128     inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
00129     inline const T *data() const { return 0; }
00130     inline T *data() { return 0; }
00131 };
00132 
00133 // more specializations for null matrices; these are necessary to resolve ambiguities
00134 template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options>
00135 : public DenseStorage<T, 0, 0, 0, _Options> { };
00136 
00137 template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options>
00138 : public DenseStorage<T, 0, 0, 0, _Options> { };
00139 
00140 template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options>
00141 : public DenseStorage<T, 0, 0, 0, _Options> { };
00142 
00143 // dynamic-size matrix with fixed-size storage
00144 template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
00145 {
00146     internal::plain_array<T,Size,_Options> m_data;
00147     DenseIndex m_rows;
00148     DenseIndex m_cols;
00149   public:
00150     inline explicit DenseStorage() : m_rows(0), m_cols(0) {}
00151     inline DenseStorage(internal::constructor_without_unaligned_array_assert)
00152       : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
00153     inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex cols) : m_rows(rows), m_cols(cols) {}
00154     inline void swap(DenseStorage& other)
00155     { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
00156     inline DenseIndex rows(void) const {return m_rows;}
00157     inline DenseIndex cols(void) const {return m_cols;}
00158     inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
00159     inline void resize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
00160     inline const T *data() const { return m_data.array; }
00161     inline T *data() { return m_data.array; }
00162 };
00163 
00164 // dynamic-size matrix with fixed-size storage and fixed width
00165 template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
00166 {
00167     internal::plain_array<T,Size,_Options> m_data;
00168     DenseIndex m_rows;
00169   public:
00170     inline explicit DenseStorage() : m_rows(0) {}
00171     inline DenseStorage(internal::constructor_without_unaligned_array_assert)
00172       : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
00173     inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex) : m_rows(rows) {}
00174     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
00175     inline DenseIndex rows(void) const {return m_rows;}
00176     inline DenseIndex cols(void) const {return _Cols;}
00177     inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
00178     inline void resize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
00179     inline const T *data() const { return m_data.array; }
00180     inline T *data() { return m_data.array; }
00181 };
00182 
00183 // dynamic-size matrix with fixed-size storage and fixed height
00184 template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
00185 {
00186     internal::plain_array<T,Size,_Options> m_data;
00187     DenseIndex m_cols;
00188   public:
00189     inline explicit DenseStorage() : m_cols(0) {}
00190     inline DenseStorage(internal::constructor_without_unaligned_array_assert)
00191       : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
00192     inline DenseStorage(DenseIndex, DenseIndex, DenseIndex cols) : m_cols(cols) {}
00193     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
00194     inline DenseIndex rows(void) const {return _Rows;}
00195     inline DenseIndex cols(void) const {return m_cols;}
00196     inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
00197     inline void resize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
00198     inline const T *data() const { return m_data.array; }
00199     inline T *data() { return m_data.array; }
00200 };
00201 
00202 // purely dynamic matrix.
00203 template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
00204 {
00205     T *m_data;
00206     DenseIndex m_rows;
00207     DenseIndex m_cols;
00208   public:
00209     inline explicit DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
00210     inline DenseStorage(internal::constructor_without_unaligned_array_assert)
00211        : m_data(0), m_rows(0), m_cols(0) {}
00212     inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex cols)
00213       : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols) 
00214     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
00215     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
00216     inline void swap(DenseStorage& other)
00217     { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
00218     inline DenseIndex rows(void) const {return m_rows;}
00219     inline DenseIndex cols(void) const {return m_cols;}
00220     inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex cols)
00221     {
00222       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
00223       m_rows = rows;
00224       m_cols = cols;
00225     }
00226     void resize(DenseIndex size, DenseIndex rows, DenseIndex cols)
00227     {
00228       if(size != m_rows*m_cols)
00229       {
00230         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
00231         if (size)
00232           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
00233         else
00234           m_data = 0;
00235         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
00236       }
00237       m_rows = rows;
00238       m_cols = cols;
00239     }
00240     inline const T *data() const { return m_data; }
00241     inline T *data() { return m_data; }
00242 };
00243 
00244 // matrix with dynamic width and fixed height (so that matrix has dynamic size).
00245 template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
00246 {
00247     T *m_data;
00248     DenseIndex m_cols;
00249   public:
00250     inline explicit DenseStorage() : m_data(0), m_cols(0) {}
00251     inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
00252     inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
00253     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
00254     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
00255     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
00256     static inline DenseIndex rows(void) {return _Rows;}
00257     inline DenseIndex cols(void) const {return m_cols;}
00258     inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols)
00259     {
00260       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
00261       m_cols = cols;
00262     }
00263     EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols)
00264     {
00265       if(size != _Rows*m_cols)
00266       {
00267         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
00268         if (size)
00269           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
00270         else
00271           m_data = 0;
00272         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
00273       }
00274       m_cols = cols;
00275     }
00276     inline const T *data() const { return m_data; }
00277     inline T *data() { return m_data; }
00278 };
00279 
00280 // matrix with dynamic height and fixed width (so that matrix has dynamic size).
00281 template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
00282 {
00283     T *m_data;
00284     DenseIndex m_rows;
00285   public:
00286     inline explicit DenseStorage() : m_data(0), m_rows(0) {}
00287     inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
00288     inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
00289     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
00290     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
00291     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
00292     inline DenseIndex rows(void) const {return m_rows;}
00293     static inline DenseIndex cols(void) {return _Cols;}
00294     inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex)
00295     {
00296       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
00297       m_rows = rows;
00298     }
00299     EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex)
00300     {
00301       if(size != m_rows*_Cols)
00302       {
00303         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
00304         if (size)
00305           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
00306         else
00307           m_data = 0;
00308         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
00309       }
00310       m_rows = rows;
00311     }
00312     inline const T *data() const { return m_data; }
00313     inline T *data() { return m_data; }
00314 };
00315 
00316 } // end namespace Eigen
00317 
00318 #endif // EIGEN_MATRIX_H