// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2012 Gael Guennebaud <[email protected]> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REF_H #define EIGEN_REF_H // IWYU pragma: private #include "./InternalHeaderCheck.h" namespace Eigen { namespace internal { traits<Ref<PlainObjectType_, Options_, StrideType_>>; traits<RefBase<Derived>>; } // namespace internal template <typename Derived> class RefBase : public MapBase<Derived> { … }; /** \class Ref * \ingroup Core_Module * * \brief A matrix or vector expression mapping an existing expression * * \tparam PlainObjectType the equivalent matrix type of the mapped data * \tparam Options specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, * \c #Aligned16, \c #Aligned8 or \c #Unaligned. The default is \c #Unaligned. \tparam StrideType optionally specifies * strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1), but accepts a * variable outer stride (leading dimension). This can be overridden by specifying strides. The type passed here must be * a specialization of the Stride template, see examples below. * * This class provides a way to write non-template functions taking Eigen objects as parameters while limiting the * number of copies. A Ref<> object can represent either a const expression or a l-value: \code * // in-out argument: * void foo1(Ref<VectorXf> x); * * // read-only const argument: * void foo2(const Ref<const VectorXf>& x); * \endcode * * In the in-out case, the input argument must satisfy the constraints of the actual Ref<> type, otherwise a compilation * issue will be triggered. By default, a Ref<VectorXf> can reference any dense vector expression of float having a * contiguous memory layout. Likewise, a Ref<MatrixXf> can reference any column-major dense matrix expression of float * whose column's elements are contiguously stored with the possibility to have a constant space in-between each column, * i.e. the inner stride must be equal to 1, but the outer stride (or leading dimension) can be greater than the number * of rows. * * In the const case, if the input expression does not match the above requirement, then it is evaluated into a * temporary before being passed to the function. Here are some examples: \code MatrixXf A; VectorXf a; foo1(a.head()); * // OK foo1(A.col()); // OK foo1(A.row()); // Compilation error because here innerstride!=1 * foo2(A.row()); // Compilation error because A.row() is a 1xN object while foo2 is expecting a Nx1 object * foo2(A.row().transpose()); // The row is copied into a contiguous temporary * foo2(2*a); // The expression is evaluated into a temporary * foo2(A.col().segment(2,4)); // No temporary * \endcode * * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameters. * Here is an example accepting an innerstride!=1: * \code * // in-out argument: * void foo3(Ref<VectorXf,0,InnerStride<> > x); * foo3(A.row()); // OK * \endcode * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to * exploit vectorization, and will involve more expensive address computations even if the input is contiguously stored * in memory. To overcome this issue, one might propose to overload internally calling a template function, e.g.: \code * // in the .h: * void foo(const Ref<MatrixXf>& A); * void foo(const Ref<MatrixXf,0,Stride<> >& A); * * // in the .cpp: * template<typename TypeOfA> void foo_impl(const TypeOfA& A) { * ... // crazy code goes here * } * void foo(const Ref<MatrixXf>& A) { foo_impl(A); } * void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); } * \endcode * * See also the following stackoverflow questions for further references: * - <a href="http://stackoverflow.com/questions/21132538/correct-usage-of-the-eigenref-class">Correct usage of the * Eigen::Ref<> class</a> * * \sa PlainObjectBase::Map(), \ref TopicStorageOrders */ template <typename PlainObjectType, int Options, typename StrideType> class Ref : public RefBase<Ref<PlainObjectType, Options, StrideType> > { … }; // this is the const ref version Ref<const TPlainObjectType, Options, StrideType>; } // end namespace Eigen #endif // EIGEN_REF_H