MOAB  4.9.3pre
Ref.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) 2012 Gael Guennebaud <[email protected]>
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       AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (int(evaluator<Derived>::Alignment) >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
00039       ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
00040       MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
00041     };
00042     typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
00043   };
00044   
00045 };
00046 
00047 template<typename Derived>
00048 struct traits<RefBase<Derived> > : public traits<Derived> {};
00049 
00050 }
00051 
00052 template<typename Derived> class RefBase
00053  : public MapBase<Derived>
00054 {
00055   typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
00056   typedef typename internal::traits<Derived>::StrideType StrideType;
00057 
00058 public:
00059 
00060   typedef MapBase<Derived> Base;
00061   EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
00062 
00063   EIGEN_DEVICE_FUNC inline Index innerStride() const
00064   {
00065     return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
00066   }
00067 
00068   EIGEN_DEVICE_FUNC inline Index outerStride() const
00069   {
00070     return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
00071          : IsVectorAtCompileTime ? this->size()
00072          : int(Flags)&RowMajorBit ? this->cols()
00073          : this->rows();
00074   }
00075 
00076   EIGEN_DEVICE_FUNC RefBase()
00077     : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
00078       // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
00079       m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
00080                StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
00081   {}
00082   
00083   EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
00084 
00085 protected:
00086 
00087   typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
00088 
00089   template<typename Expression>
00090   EIGEN_DEVICE_FUNC void construct(Expression& expr)
00091   {
00092     if(PlainObjectType::RowsAtCompileTime==1)
00093     {
00094       eigen_assert(expr.rows()==1 || expr.cols()==1);
00095       ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
00096     }
00097     else if(PlainObjectType::ColsAtCompileTime==1)
00098     {
00099       eigen_assert(expr.rows()==1 || expr.cols()==1);
00100       ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
00101     }
00102     else
00103       ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
00104     
00105     if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
00106       ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
00107     else
00108       ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
00109                                    StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());    
00110   }
00111 
00112   StrideBase m_stride;
00113 };
00114 
00184 template<typename PlainObjectType, int Options, typename StrideType> class Ref
00185   : public RefBase<Ref<PlainObjectType, Options, StrideType> >
00186 {
00187   private:
00188     typedef internal::traits<Ref> Traits;
00189     template<typename Derived>
00190     EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr,
00191                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
00192   public:
00193 
00194     typedef RefBase<Ref> Base;
00195     EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00196 
00197 
00198     #ifndef EIGEN_PARSED_BY_DOXYGEN
00199     template<typename Derived>
00200     EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr,
00201                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00202     {
00203       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00204       Base::construct(expr.derived());
00205     }
00206     template<typename Derived>
00207     EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
00208                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00209     #else
00210 
00211     template<typename Derived>
00212     inline Ref(DenseBase<Derived>& expr)
00213     #endif
00214     {
00215       EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
00216       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00217       EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
00218       Base::construct(expr.const_cast_derived());
00219     }
00220 
00221     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
00222 
00223 };
00224 
00225 // this is the const ref version
00226 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
00227   : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
00228 {
00229     typedef internal::traits<Ref> Traits;
00230   public:
00231 
00232     typedef RefBase<Ref> Base;
00233     EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00234 
00235     template<typename Derived>
00236     EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
00237                                  typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
00238     {
00239 //      std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
00240 //      std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
00241 //      std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
00242       construct(expr.derived(), typename Traits::template match<Derived>::type());
00243     }
00244 
00245     EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) {
00246       // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
00247     }
00248 
00249     template<typename OtherRef>
00250     EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) {
00251       construct(other.derived(), typename Traits::template match<OtherRef>::type());
00252     }
00253 
00254   protected:
00255 
00256     template<typename Expression>
00257     EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
00258     {
00259       Base::construct(expr);
00260     }
00261 
00262     template<typename Expression>
00263     EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
00264     {
00265       internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar>());
00266       Base::construct(m_object);
00267     }
00268 
00269   protected:
00270     TPlainObjectType m_object;
00271 };
00272 
00273 } // end namespace Eigen
00274 
00275 #endif // EIGEN_REF_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines