Eigen  3.3.3
Ref.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_REF_H
00011 #define EIGEN_REF_H
00012 
00013 namespace Eigen { 
00014 
00015 namespace internal {
00016 
00017 template<typename _PlainObjectType, int _Options, typename _StrideType>
00018 struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
00019   : public traits<Map<_PlainObjectType, _Options, _StrideType> >
00020 {
00021   typedef _PlainObjectType PlainObjectType;
00022   typedef _StrideType StrideType;
00023   enum {
00024     Options = _Options,
00025     Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit,
00026     Alignment = traits<Map<_PlainObjectType, _Options, _StrideType> >::Alignment
00027   };
00028 
00029   template<typename Derived> struct match {
00030     enum {
00031       HasDirectAccess = internal::has_direct_access<Derived>::ret,
00032       StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
00033       InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
00034                       || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
00035                       || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
00036       OuterStrideMatch = Derived::IsVectorAtCompileTime
00037                       || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
00038       // NOTE, this indirection of evaluator<Derived>::Alignment is needed
00039       // to workaround a very strange bug in MSVC related to the instantiation
00040       // of has_*ary_operator in evaluator<CwiseNullaryOp>.
00041       // This line is surprisingly very sensitive. For instance, simply adding parenthesis
00042       // as "DerivedAlignment = (int(evaluator<Derived>::Alignment))," will make MSVC fail...
00043       DerivedAlignment = int(evaluator<Derived>::Alignment),
00044       AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (DerivedAlignment >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
00045       ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
00046       MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
00047     };
00048     typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
00049   };
00050   
00051 };
00052 
00053 template<typename Derived>
00054 struct traits<RefBase<Derived> > : public traits<Derived> {};
00055 
00056 }
00057 
00058 template<typename Derived> class RefBase
00059  : public MapBase<Derived>
00060 {
00061   typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
00062   typedef typename internal::traits<Derived>::StrideType StrideType;
00063 
00064 public:
00065 
00066   typedef MapBase<Derived> Base;
00067   EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
00068 
00069   EIGEN_DEVICE_FUNC inline Index innerStride() const
00070   {
00071     return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
00072   }
00073 
00074   EIGEN_DEVICE_FUNC inline Index outerStride() const
00075   {
00076     return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
00077          : IsVectorAtCompileTime ? this->size()
00078          : int(Flags)&RowMajorBit ? this->cols()
00079          : this->rows();
00080   }
00081 
00082   EIGEN_DEVICE_FUNC RefBase()
00083     : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
00084       // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
00085       m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
00086                StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
00087   {}
00088   
00089   EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
00090 
00091 protected:
00092 
00093   typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
00094 
00095   template<typename Expression>
00096   EIGEN_DEVICE_FUNC void construct(Expression& expr)
00097   {
00098     if(PlainObjectType::RowsAtCompileTime==1)
00099     {
00100       eigen_assert(expr.rows()==1 || expr.cols()==1);
00101       ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
00102     }
00103     else if(PlainObjectType::ColsAtCompileTime==1)
00104     {
00105       eigen_assert(expr.rows()==1 || expr.cols()==1);
00106       ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
00107     }
00108     else
00109       ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
00110     
00111     if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
00112       ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
00113     else
00114       ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
00115                                    StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());    
00116   }
00117 
00118   StrideBase m_stride;
00119 };
00120 
00190 template<typename PlainObjectType, int Options, typename StrideType> class Ref
00191   : public RefBase<Ref<PlainObjectType, Options, StrideType> >
00192 {
00193   private:
00194     typedef internal::traits<Ref> Traits;
00195     template<typename Derived>
00196     EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr,
00197                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
00198   public:
00199 
00200     typedef RefBase<Ref> Base;
00201     EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00202 
00203 
00204     #ifndef EIGEN_PARSED_BY_DOXYGEN
00205     template<typename Derived>
00206     EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr,
00207                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00208     {
00209       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00210       Base::construct(expr.derived());
00211     }
00212     template<typename Derived>
00213     EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
00214                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00215     #else
00216 
00217     template<typename Derived>
00218     inline Ref(DenseBase<Derived>& expr)
00219     #endif
00220     {
00221       EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
00222       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00223       EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
00224       Base::construct(expr.const_cast_derived());
00225     }
00226 
00227     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
00228 
00229 };
00230 
00231 // this is the const ref version
00232 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
00233   : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
00234 {
00235     typedef internal::traits<Ref> Traits;
00236   public:
00237 
00238     typedef RefBase<Ref> Base;
00239     EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00240 
00241     template<typename Derived>
00242     EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
00243                                  typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
00244     {
00245 //      std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
00246 //      std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
00247 //      std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
00248       construct(expr.derived(), typename Traits::template match<Derived>::type());
00249     }
00250 
00251     EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) {
00252       // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
00253     }
00254 
00255     template<typename OtherRef>
00256     EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) {
00257       construct(other.derived(), typename Traits::template match<OtherRef>::type());
00258     }
00259 
00260   protected:
00261 
00262     template<typename Expression>
00263     EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
00264     {
00265       Base::construct(expr);
00266     }
00267 
00268     template<typename Expression>
00269     EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
00270     {
00271       internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar,Scalar>());
00272       Base::construct(m_object);
00273     }
00274 
00275   protected:
00276     TPlainObjectType m_object;
00277 };
00278 
00279 } // end namespace Eigen
00280 
00281 #endif // EIGEN_REF_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends