Eigen  3.2.1
 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 <gael.guennebaud@inria.fr>
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 || ((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  MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch
112  };
113  typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
114  };
115 
116 };
117 
118 template<typename Derived>
119 struct traits<RefBase<Derived> > : public traits<Derived> {};
120 
121 }
122 
123 template<typename Derived> class RefBase
124  : public MapBase<Derived>
125 {
126  typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
127  typedef typename internal::traits<Derived>::StrideType StrideType;
128 
129 public:
130 
131  typedef MapBase<Derived> Base;
132  EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
133 
134  inline Index innerStride() const
135  {
136  return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
137  }
138 
139  inline Index outerStride() const
140  {
141  return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
142  : IsVectorAtCompileTime ? this->size()
143  : int(Flags)&RowMajorBit ? this->cols()
144  : this->rows();
145  }
146 
147  RefBase()
148  : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
149  // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
150  m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
151  StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
152  {}
153 
154  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
155 
156 protected:
157 
158  typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
159 
160  template<typename Expression>
161  void construct(Expression& expr)
162  {
163  if(PlainObjectType::RowsAtCompileTime==1)
164  {
165  eigen_assert(expr.rows()==1 || expr.cols()==1);
166  ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
167  }
168  else if(PlainObjectType::ColsAtCompileTime==1)
169  {
170  eigen_assert(expr.rows()==1 || expr.cols()==1);
171  ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
172  }
173  else
174  ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
175  ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
176  StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
177  }
178 
179  StrideBase m_stride;
180 };
181 
182 
183 template<typename PlainObjectType, int Options, typename StrideType> class Ref
184  : public RefBase<Ref<PlainObjectType, Options, StrideType> >
185 {
186  typedef internal::traits<Ref> Traits;
187  public:
188 
189  typedef RefBase<Ref> Base;
190  EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
191 
192 
193  #ifndef EIGEN_PARSED_BY_DOXYGEN
194  template<typename Derived>
195  inline Ref(PlainObjectBase<Derived>& expr,
196  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
197  {
198  Base::construct(expr);
199  }
200  template<typename Derived>
201  inline Ref(const DenseBase<Derived>& expr,
202  typename internal::enable_if<bool(internal::is_lvalue<Derived>::value&&bool(Traits::template match<Derived>::MatchAtCompileTime)),Derived>::type* = 0,
203  int = Derived::ThisConstantIsPrivateInPlainObjectBase)
204  #else
205  template<typename Derived>
206  inline Ref(DenseBase<Derived>& expr)
207  #endif
208  {
209  Base::construct(expr.const_cast_derived());
210  }
211 
212  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
213 
214 };
215 
216 // this is the const ref version
217 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
218  : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
219 {
220  typedef internal::traits<Ref> Traits;
221  public:
222 
223  typedef RefBase<Ref> Base;
224  EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
225 
226  template<typename Derived>
227  inline Ref(const DenseBase<Derived>& expr)
228  {
229 // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
230 // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
231 // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
232  construct(expr.derived(), typename Traits::template match<Derived>::type());
233  }
234 
235  protected:
236 
237  template<typename Expression>
238  void construct(const Expression& expr,internal::true_type)
239  {
240  Base::construct(expr);
241  }
242 
243  template<typename Expression>
244  void construct(const Expression& expr, internal::false_type)
245  {
246  m_object.lazyAssign(expr);
247  Base::construct(m_object);
248  }
249 
250  protected:
251  TPlainObjectType m_object;
252 };
253 
254 } // end namespace Eigen
255 
256 #endif // EIGEN_REF_H
const int Dynamic
Definition: Constants.h:21
A matrix or vector expression mapping an existing expressions.
Definition: Ref.h:17
Definition: Constants.h:194
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