MapBase.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef EIGEN_MAPBASE_H
27 #define EIGEN_MAPBASE_H
28 
29 #define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
30  EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
31  YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
32 
33 namespace Eigen {
34 
42 template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
43  : public internal::dense_xpr_base<Derived>::type
44 {
45  public:
46 
47  typedef typename internal::dense_xpr_base<Derived>::type Base;
48  enum {
49  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
50  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
51  SizeAtCompileTime = Base::SizeAtCompileTime
52  };
53 
54  typedef typename internal::traits<Derived>::StorageKind StorageKind;
55  typedef typename internal::traits<Derived>::Index Index;
56  typedef typename internal::traits<Derived>::Scalar Scalar;
57  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
59  typedef typename internal::conditional<
60  bool(internal::is_lvalue<Derived>::value),
61  Scalar *,
62  const Scalar *>::type
64 
65  using Base::derived;
66 // using Base::RowsAtCompileTime;
67 // using Base::ColsAtCompileTime;
68 // using Base::SizeAtCompileTime;
69  using Base::MaxRowsAtCompileTime;
70  using Base::MaxColsAtCompileTime;
71  using Base::MaxSizeAtCompileTime;
72  using Base::IsVectorAtCompileTime;
73  using Base::Flags;
74  using Base::IsRowMajor;
75 
76  using Base::rows;
77  using Base::cols;
78  using Base::size;
79  using Base::coeff;
80  using Base::coeffRef;
81  using Base::lazyAssign;
82  using Base::eval;
83 
84  using Base::innerStride;
85  using Base::outerStride;
86  using Base::rowStride;
87  using Base::colStride;
88 
89  // bug 217 - compile error on ICC 11.1
90  using Base::operator=;
91 
92  typedef typename Base::CoeffReturnType CoeffReturnType;
93 
94  inline Index rows() const { return m_rows.value(); }
95  inline Index cols() const { return m_cols.value(); }
96 
103  inline const Scalar* data() const { return m_data; }
104 
105  inline const Scalar& coeff(Index row, Index col) const
106  {
107  return m_data[col * colStride() + row * rowStride()];
108  }
109 
110  inline const Scalar& coeff(Index index) const
111  {
113  return m_data[index * innerStride()];
114  }
115 
116  inline const Scalar& coeffRef(Index row, Index col) const
117  {
118  return this->m_data[col * colStride() + row * rowStride()];
119  }
120 
121  inline const Scalar& coeffRef(Index index) const
122  {
124  return this->m_data[index * innerStride()];
125  }
126 
127  template<int LoadMode>
128  inline PacketScalar packet(Index row, Index col) const
129  {
130  return internal::ploadt<PacketScalar, LoadMode>
131  (m_data + (col * colStride() + row * rowStride()));
132  }
133 
134  template<int LoadMode>
135  inline PacketScalar packet(Index index) const
136  {
138  return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
139  }
140 
141  inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
142  {
144  checkSanity();
145  }
146 
147  inline MapBase(PointerType data, Index size)
148  : m_data(data),
149  m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
150  m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime))
151  {
153  eigen_assert(size >= 0);
154  eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
155  checkSanity();
156  }
157 
158  inline MapBase(PointerType data, Index rows, Index cols)
159  : m_data(data), m_rows(rows), m_cols(cols)
160  {
161  eigen_assert( (data == 0)
162  || ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
163  && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
164  checkSanity();
165  }
166 
167  protected:
168 
169  void checkSanity() const
170  {
171  EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
172  internal::inner_stride_at_compile_time<Derived>::ret==1),
173  PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
174  eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
175  && "data is not aligned");
176  }
177 
179  const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
180  const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
181 };
182 
183 template<typename Derived> class MapBase<Derived, WriteAccessors>
184  : public MapBase<Derived, ReadOnlyAccessors>
185 {
186  public:
187 
189 
190  typedef typename Base::Scalar Scalar;
191  typedef typename Base::PacketScalar PacketScalar;
192  typedef typename Base::Index Index;
193  typedef typename Base::PointerType PointerType;
194 
195  using Base::derived;
196  using Base::rows;
197  using Base::cols;
198  using Base::size;
199  using Base::coeff;
200  using Base::coeffRef;
201 
202  using Base::innerStride;
203  using Base::outerStride;
204  using Base::rowStride;
205  using Base::colStride;
206 
207  typedef typename internal::conditional<
208  internal::is_lvalue<Derived>::value,
209  Scalar,
210  const Scalar
212 
213  inline const Scalar* data() const { return this->m_data; }
214  inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
215 
217  {
218  return this->m_data[col * colStride() + row * rowStride()];
219  }
220 
221  inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
222  {
224  return this->m_data[index * innerStride()];
225  }
226 
227  template<int StoreMode>
228  inline void writePacket(Index row, Index col, const PacketScalar& x)
229  {
230  internal::pstoret<Scalar, PacketScalar, StoreMode>
231  (this->m_data + (col * colStride() + row * rowStride()), x);
232  }
233 
234  template<int StoreMode>
235  inline void writePacket(Index index, const PacketScalar& x)
236  {
238  internal::pstoret<Scalar, PacketScalar, StoreMode>
239  (this->m_data + index * innerStride(), x);
240  }
241 
242  explicit inline MapBase(PointerType data) : Base(data) {}
243  inline MapBase(PointerType data, Index size) : Base(data, size) {}
244  inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
245 
246  Derived& operator=(const MapBase& other)
247  {
248  Base::Base::operator=(other);
249  return derived();
250  }
251 
252  using Base::Base::operator=;
253 };
254 
255 } // end namespace Eigen
256 
257 #endif // EIGEN_MAPBASE_H