MapBase.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) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 #ifndef EIGEN_MAPBASE_H
00027 #define EIGEN_MAPBASE_H
00028 
00029 #define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
00030       EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
00031                           YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
00032 
00033 namespace Eigen { 
00034 
00042 template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
00043   : public internal::dense_xpr_base<Derived>::type
00044 {
00045   public:
00046 
00047     typedef typename internal::dense_xpr_base<Derived>::type Base;
00048     enum {
00049       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00050       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00051       SizeAtCompileTime = Base::SizeAtCompileTime
00052     };
00053 
00054     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00055     typedef typename internal::traits<Derived>::Index Index;
00056     typedef typename internal::traits<Derived>::Scalar Scalar;
00057     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00058     typedef typename NumTraits<Scalar>::Real RealScalar;
00059     typedef typename internal::conditional<
00060                          bool(internal::is_lvalue<Derived>::value),
00061                          Scalar *,
00062                          const Scalar *>::type
00063                      PointerType;
00064 
00065     using Base::derived;
00066 //    using Base::RowsAtCompileTime;
00067 //    using Base::ColsAtCompileTime;
00068 //    using Base::SizeAtCompileTime;
00069     using Base::MaxRowsAtCompileTime;
00070     using Base::MaxColsAtCompileTime;
00071     using Base::MaxSizeAtCompileTime;
00072     using Base::IsVectorAtCompileTime;
00073     using Base::Flags;
00074     using Base::IsRowMajor;
00075 
00076     using Base::rows;
00077     using Base::cols;
00078     using Base::size;
00079     using Base::coeff;
00080     using Base::coeffRef;
00081     using Base::lazyAssign;
00082     using Base::eval;
00083 
00084     using Base::innerStride;
00085     using Base::outerStride;
00086     using Base::rowStride;
00087     using Base::colStride;
00088 
00089     // bug 217 - compile error on ICC 11.1
00090     using Base::operator=;
00091 
00092     typedef typename Base::CoeffReturnType CoeffReturnType;
00093 
00094     inline Index rows() const { return m_rows.value(); }
00095     inline Index cols() const { return m_cols.value(); }
00096 
00103     inline const Scalar* data() const { return m_data; }
00104 
00105     inline const Scalar& coeff(Index row, Index col) const
00106     {
00107       return m_data[col * colStride() + row * rowStride()];
00108     }
00109 
00110     inline const Scalar& coeff(Index index) const
00111     {
00112       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
00113       return m_data[index * innerStride()];
00114     }
00115 
00116     inline const Scalar& coeffRef(Index row, Index col) const
00117     {
00118       return this->m_data[col * colStride() + row * rowStride()];
00119     }
00120 
00121     inline const Scalar& coeffRef(Index index) const
00122     {
00123       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
00124       return this->m_data[index * innerStride()];
00125     }
00126 
00127     template<int LoadMode>
00128     inline PacketScalar packet(Index row, Index col) const
00129     {
00130       return internal::ploadt<PacketScalar, LoadMode>
00131                (m_data + (col * colStride() + row * rowStride()));
00132     }
00133 
00134     template<int LoadMode>
00135     inline PacketScalar packet(Index index) const
00136     {
00137       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
00138       return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
00139     }
00140 
00141     inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
00142     {
00143       EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
00144       checkSanity();
00145     }
00146 
00147     inline MapBase(PointerType data, Index size)
00148             : m_data(data),
00149               m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
00150               m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime))
00151     {
00152       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00153       eigen_assert(size >= 0);
00154       eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00155       checkSanity();
00156     }
00157 
00158     inline MapBase(PointerType data, Index rows, Index cols)
00159             : m_data(data), m_rows(rows), m_cols(cols)
00160     {
00161       eigen_assert( (data == 0)
00162               || (   rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00163                   && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
00164       checkSanity();
00165     }
00166 
00167   protected:
00168 
00169     void checkSanity() const
00170     {
00171       EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
00172                                         internal::inner_stride_at_compile_time<Derived>::ret==1),
00173                           PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
00174       eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
00175                    && "data is not aligned");
00176     }
00177 
00178     PointerType m_data;
00179     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
00180     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
00181 };
00182 
00183 template<typename Derived> class MapBase<Derived, WriteAccessors>
00184   : public MapBase<Derived, ReadOnlyAccessors>
00185 {
00186   public:
00187 
00188     typedef MapBase<Derived, ReadOnlyAccessors> Base;
00189 
00190     typedef typename Base::Scalar Scalar;
00191     typedef typename Base::PacketScalar PacketScalar;
00192     typedef typename Base::Index Index;
00193     typedef typename Base::PointerType PointerType;
00194 
00195     using Base::derived;
00196     using Base::rows;
00197     using Base::cols;
00198     using Base::size;
00199     using Base::coeff;
00200     using Base::coeffRef;
00201 
00202     using Base::innerStride;
00203     using Base::outerStride;
00204     using Base::rowStride;
00205     using Base::colStride;
00206 
00207     typedef typename internal::conditional<
00208                     internal::is_lvalue<Derived>::value,
00209                     Scalar,
00210                     const Scalar
00211                   >::type ScalarWithConstIfNotLvalue;
00212 
00213     inline const Scalar* data() const { return this->m_data; }
00214     inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
00215 
00216     inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
00217     {
00218       return this->m_data[col * colStride() + row * rowStride()];
00219     }
00220 
00221     inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
00222     {
00223       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
00224       return this->m_data[index * innerStride()];
00225     }
00226 
00227     template<int StoreMode>
00228     inline void writePacket(Index row, Index col, const PacketScalar& x)
00229     {
00230       internal::pstoret<Scalar, PacketScalar, StoreMode>
00231                (this->m_data + (col * colStride() + row * rowStride()), x);
00232     }
00233 
00234     template<int StoreMode>
00235     inline void writePacket(Index index, const PacketScalar& x)
00236     {
00237       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
00238       internal::pstoret<Scalar, PacketScalar, StoreMode>
00239                 (this->m_data + index * innerStride(), x);
00240     }
00241 
00242     explicit inline MapBase(PointerType data) : Base(data) {}
00243     inline MapBase(PointerType data, Index size) : Base(data, size) {}
00244     inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
00245 
00246     Derived& operator=(const MapBase& other)
00247     {
00248       Base::Base::operator=(other);
00249       return derived();
00250     }
00251 
00252     using Base::Base::operator=;
00253 };
00254 
00255 } // end namespace Eigen
00256 
00257 #endif // EIGEN_MAPBASE_H