// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2012 Gael Guennebaud // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_REF_H #define EIGEN_REF_H namespace Eigen { template,OuterStride<> >::type > class Ref; /** \class Ref * \ingroup Core_Module * * \brief A matrix or vector expression mapping an existing expressions * * \tparam PlainObjectType the equivalent matrix type of the mapped data * \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. * The default is \c #Unaligned. * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout * of an ordinary, contiguous array. This can be overridden by specifying strides. * The type passed here must be a specialization of the Stride template, see examples below. * * * \sa PlainObjectBase::Map(), \ref TopicStorageOrders */ namespace internal { template struct traits > : public traits > {}; template struct ref_match_helper { enum { HasDirectAccess = internal::has_direct_access::ret, StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) || int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1, OuterStrideMatch = Derived::IsVectorAtCompileTime || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch }; typedef typename internal::conditional::type type; }; } template class Ref : public MapBase > { public: typedef MapBase Base; EIGEN_DENSE_PUBLIC_INTERFACE(Ref) inline Index innerStride() const { return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; } inline Index outerStride() const { return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() : IsVectorAtCompileTime ? this->size() : int(Flags)&RowMajorBit ? this->cols() : this->rows(); } template inline Ref(PlainObjectBase& expr, typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), m_stride( StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()) { construct(expr); } template inline Ref(const MatrixBase& expr, typename internal::enable_if::value&&bool(internal::ref_match_helper::MatchAtCompileTime)),Derived>::type* = 0, int = Derived::ThisConstantIsPrivateInPlainObjectBase) : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), m_stride( StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()) { construct(expr.const_cast_derived()); } EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) protected: typedef internal::variable_if_dynamic MRowsType; typedef internal::variable_if_dynamic MColsType; typedef Stride StrideBase; template void construct(Expression& expr) { if(PlainObjectType::RowsAtCompileTime==1) { eigen_assert(expr.rows()==1 || expr.cols()==1); ::new (static_cast(this)) Base(expr.data(), 1, expr.size()); } else if(PlainObjectType::ColsAtCompileTime==1) { eigen_assert(expr.rows()==1 || expr.cols()==1); ::new (static_cast(this)) Base(expr.data(), expr.size(), 1); } else ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); } protected: StrideBase m_stride; }; // this is the const ref version template class Ref : public MapBase > { public: typedef MapBase Base; EIGEN_DENSE_PUBLIC_INTERFACE(Ref) inline Index innerStride() const { return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; } inline Index outerStride() const { return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() : IsVectorAtCompileTime ? this->size() : int(Flags)&RowMajorBit ? this->cols() : this->rows(); } template inline Ref(const MatrixBase& expr) : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) { construct(expr.derived(), typename internal::ref_match_helper::type()); } EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) protected: typedef internal::variable_if_dynamic MRowsType; typedef internal::variable_if_dynamic MColsType; typedef Stride StrideBase; template void construct(const Expression& expr,internal::true_type) { if(PlainObjectType::RowsAtCompileTime==1) { eigen_assert(expr.rows()==1 || expr.cols()==1); ::new (static_cast(this)) Base(expr.data(), 1, expr.size()); } else if(PlainObjectType::ColsAtCompileTime==1) { eigen_assert(expr.rows()==1 || expr.cols()==1); ::new (static_cast(this)) Base(expr.data(), expr.size(), 1); } else ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); } template void construct(const Expression& expr, internal::false_type) { //std::cout << "const Ref: copy\n"; m_object = expr; construct(m_object, internal::true_type()); } protected: StrideBase m_stride; PlainObjectType m_object; }; } // end namespace Eigen #endif // EIGEN_REF_H