Eigen  3.2.7
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ref.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2012 Gael Guennebaud <[email protected]>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_REF_H
11 #define EIGEN_REF_H
12 
13 namespace Eigen {
14 
15 template<typename Derived> class RefBase;
16 template<typename PlainObjectType, int Options = 0,
17  typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
18 
88 namespace internal {
89 
90 template<typename _PlainObjectType, int _Options, typename _StrideType>
91 struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
92  : public traits<Map<_PlainObjectType, _Options, _StrideType> >
93 {
94  typedef _PlainObjectType PlainObjectType;
95  typedef _StrideType StrideType;
96  enum {
97  Options = _Options,
98  Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit
99  };
100 
101  template<typename Derived> struct match {
102  enum {
103  HasDirectAccess = internal::has_direct_access<Derived>::ret,
104  StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
105  InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
106  || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
107  || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
108  OuterStrideMatch = Derived::IsVectorAtCompileTime
109  || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
110  AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),
111  ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
112  MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
113  };
114  typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
115  };
116 
117 };
118 
119 template<typename Derived>
120 struct traits<RefBase<Derived> > : public traits<Derived> {};
121 
122 }
123 
124 template<typename Derived> class RefBase
125  : public MapBase<Derived>
126 {
127  typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
128  typedef typename internal::traits<Derived>::StrideType StrideType;
129 
130 public:
131 
132  typedef MapBase<Derived> Base;
133  EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
134 
135  inline Index innerStride() const
136  {
137  return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
138  }
139 
140  inline Index outerStride() const
141  {
142  return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
143  : IsVectorAtCompileTime ? this->size()
144  : int(Flags)&RowMajorBit ? this->cols()
145  : this->rows();
146  }
147 
148  RefBase()
149  : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
150  // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
151  m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
152  StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
153  {}
154 
155  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
156 
157 protected:
158 
159  typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
160 
161  template<typename Expression>
162  void construct(Expression& expr)
163  {
164  if(PlainObjectType::RowsAtCompileTime==1)
165  {
166  eigen_assert(expr.rows()==1 || expr.cols()==1);
167  ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
168  }
169  else if(PlainObjectType::ColsAtCompileTime==1)
170  {
171  eigen_assert(expr.rows()==1 || expr.cols()==1);
172  ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
173  }
174  else
175  ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
176 
177  if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
178  ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
179  else
180  ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
181  StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
182  }
183 
184  StrideBase m_stride;
185 };
186 
187 
188 template<typename PlainObjectType, int Options, typename StrideType> class Ref
189  : public RefBase<Ref<PlainObjectType, Options, StrideType> >
190 {
191  private:
192  typedef internal::traits<Ref> Traits;
193  template<typename Derived>
194  inline Ref(const PlainObjectBase<Derived>& expr,
195  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
196  public:
197 
198  typedef RefBase<Ref> Base;
199  EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
200 
201 
202  #ifndef EIGEN_PARSED_BY_DOXYGEN
203  template<typename Derived>
204  inline Ref(PlainObjectBase<Derived>& expr,
205  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
206  {
207  EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
208  Base::construct(expr.derived());
209  }
210  template<typename Derived>
211  inline Ref(const DenseBase<Derived>& expr,
212  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
213  #else
214  template<typename Derived>
215  inline Ref(DenseBase<Derived>& expr)
216  #endif
217  {
218  EIGEN_STATIC_ASSERT(static_cast<bool>(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
219  EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
220  enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
221  Base::construct(expr.const_cast_derived());
222  }
223 
224  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
225 
226 };
227 
228 // this is the const ref version
229 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
230  : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
231 {
232  typedef internal::traits<Ref> Traits;
233  public:
234 
235  typedef RefBase<Ref> Base;
236  EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
237 
238  template<typename Derived>
239  inline Ref(const DenseBase<Derived>& expr,
240  typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
241  {
242 // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
243 // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
244 // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
245  construct(expr.derived(), typename Traits::template match<Derived>::type());
246  }
247 
248  inline Ref(const Ref& other) : Base(other) {
249  // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
250  }
251 
252  template<typename OtherRef>
253  inline Ref(const RefBase<OtherRef>& other) {
254  construct(other.derived(), typename Traits::template match<OtherRef>::type());
255  }
256 
257  protected:
258 
259  template<typename Expression>
260  void construct(const Expression& expr,internal::true_type)
261  {
262  Base::construct(expr);
263  }
264 
265  template<typename Expression>
266  void construct(const Expression& expr, internal::false_type)
267  {
268  m_object.lazyAssign(expr);
269  Base::construct(m_object);
270  }
271 
272  protected:
273  TPlainObjectType m_object;
274 };
275 
276 } // end namespace Eigen
277 
278 #endif // EIGEN_REF_H
const int Dynamic
Definition: Constants.h:21
Definition: Constants.h:194
A matrix or vector expression mapping an existing expressions.
Definition: Ref.h:17
const unsigned int RowMajorBit
Definition: Constants.h:53
Convenience specialization of Stride to specify only an outer stride See class Map for some examples...
Definition: Stride.h:97
const unsigned int AlignedBit
Definition: Constants.h:147