Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_DENSEBASE_H
     12 #define EIGEN_DENSEBASE_H
     13 
     14 namespace Eigen {
     15 
     16 /** \class DenseBase
     17   * \ingroup Core_Module
     18   *
     19   * \brief Base class for all dense matrices, vectors, and arrays
     20   *
     21   * This class is the base that is inherited by all dense objects (matrix, vector, arrays,
     22   * and related expression types). The common Eigen API for dense objects is contained in this class.
     23   *
     24   * \tparam Derived is the derived type, e.g., a matrix type or an expression.
     25   *
     26   * This class can be extended with the help of the plugin mechanism described on the page
     27   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
     28   *
     29   * \sa \ref TopicClassHierarchy
     30   */
     31 template<typename Derived> class DenseBase
     32 #ifndef EIGEN_PARSED_BY_DOXYGEN
     33   : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
     34                                      typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>
     35 #else
     36   : public DenseCoeffsBase<Derived>
     37 #endif // not EIGEN_PARSED_BY_DOXYGEN
     38 {
     39   public:
     40     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
     41                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
     42 
     43     class InnerIterator;
     44 
     45     typedef typename internal::traits<Derived>::StorageKind StorageKind;
     46 
     47     /** \brief The type of indices
     48       * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
     49       * \sa \ref TopicPreprocessorDirectives.
     50       */
     51     typedef typename internal::traits<Derived>::Index Index;
     52 
     53     typedef typename internal::traits<Derived>::Scalar Scalar;
     54     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
     55     typedef typename NumTraits<Scalar>::Real RealScalar;
     56 
     57     typedef DenseCoeffsBase<Derived> Base;
     58     using Base::derived;
     59     using Base::const_cast_derived;
     60     using Base::rows;
     61     using Base::cols;
     62     using Base::size;
     63     using Base::rowIndexByOuterInner;
     64     using Base::colIndexByOuterInner;
     65     using Base::coeff;
     66     using Base::coeffByOuterInner;
     67     using Base::packet;
     68     using Base::packetByOuterInner;
     69     using Base::writePacket;
     70     using Base::writePacketByOuterInner;
     71     using Base::coeffRef;
     72     using Base::coeffRefByOuterInner;
     73     using Base::copyCoeff;
     74     using Base::copyCoeffByOuterInner;
     75     using Base::copyPacket;
     76     using Base::copyPacketByOuterInner;
     77     using Base::operator();
     78     using Base::operator[];
     79     using Base::x;
     80     using Base::y;
     81     using Base::z;
     82     using Base::w;
     83     using Base::stride;
     84     using Base::innerStride;
     85     using Base::outerStride;
     86     using Base::rowStride;
     87     using Base::colStride;
     88     typedef typename Base::CoeffReturnType CoeffReturnType;
     89 
     90     enum {
     91 
     92       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
     93         /**< The number of rows at compile-time. This is just a copy of the value provided
     94           * by the \a Derived type. If a value is not known at compile-time,
     95           * it is set to the \a Dynamic constant.
     96           * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
     97 
     98       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
     99         /**< The number of columns at compile-time. This is just a copy of the value provided
    100           * by the \a Derived type. If a value is not known at compile-time,
    101           * it is set to the \a Dynamic constant.
    102           * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
    103 
    104 
    105       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
    106                                                    internal::traits<Derived>::ColsAtCompileTime>::ret),
    107         /**< This is equal to the number of coefficients, i.e. the number of
    108           * rows times the number of columns, or to \a Dynamic if this is not
    109           * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
    110 
    111       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
    112         /**< This value is equal to the maximum possible number of rows that this expression
    113           * might have. If this expression might have an arbitrarily high number of rows,
    114           * this value is set to \a Dynamic.
    115           *
    116           * This value is useful to know when evaluating an expression, in order to determine
    117           * whether it is possible to avoid doing a dynamic memory allocation.
    118           *
    119           * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime
    120           */
    121 
    122       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
    123         /**< This value is equal to the maximum possible number of columns that this expression
    124           * might have. If this expression might have an arbitrarily high number of columns,
    125           * this value is set to \a Dynamic.
    126           *
    127           * This value is useful to know when evaluating an expression, in order to determine
    128           * whether it is possible to avoid doing a dynamic memory allocation.
    129           *
    130           * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
    131           */
    132 
    133       MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
    134                                                       internal::traits<Derived>::MaxColsAtCompileTime>::ret),
    135         /**< This value is equal to the maximum possible number of coefficients that this expression
    136           * might have. If this expression might have an arbitrarily high number of coefficients,
    137           * this value is set to \a Dynamic.
    138           *
    139           * This value is useful to know when evaluating an expression, in order to determine
    140           * whether it is possible to avoid doing a dynamic memory allocation.
    141           *
    142           * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
    143           */
    144 
    145       IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
    146                            || internal::traits<Derived>::MaxColsAtCompileTime == 1,
    147         /**< This is set to true if either the number of rows or the number of
    148           * columns is known at compile-time to be equal to 1. Indeed, in that case,
    149           * we are dealing with a column-vector (if there is only one column) or with
    150           * a row-vector (if there is only one row). */
    151 
    152       Flags = internal::traits<Derived>::Flags,
    153         /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
    154           * constructed from this one. See the \ref flags "list of flags".
    155           */
    156 
    157       IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
    158 
    159       InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
    160                              : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
    161 
    162       CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
    163         /**< This is a rough measure of how expensive it is to read one coefficient from
    164           * this expression.
    165           */
    166 
    167       InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
    168       OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
    169     };
    170 
    171     enum { ThisConstantIsPrivateInPlainObjectBase };
    172 
    173     /** \returns the number of nonzero coefficients which is in practice the number
    174       * of stored coefficients. */
    175     inline Index nonZeros() const { return size(); }
    176     /** \returns true if either the number of rows or the number of columns is equal to 1.
    177       * In other words, this function returns
    178       * \code rows()==1 || cols()==1 \endcode
    179       * \sa rows(), cols(), IsVectorAtCompileTime. */
    180 
    181     /** \returns the outer size.
    182       *
    183       * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
    184       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
    185       * column-major matrix, and the number of rows for a row-major matrix. */
    186     Index outerSize() const
    187     {
    188       return IsVectorAtCompileTime ? 1
    189            : int(IsRowMajor) ? this->rows() : this->cols();
    190     }
    191 
    192     /** \returns the inner size.
    193       *
    194       * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
    195       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
    196       * column-major matrix, and the number of columns for a row-major matrix. */
    197     Index innerSize() const
    198     {
    199       return IsVectorAtCompileTime ? this->size()
    200            : int(IsRowMajor) ? this->cols() : this->rows();
    201     }
    202 
    203     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
    204       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
    205       * nothing else.
    206       */
    207     void resize(Index size)
    208     {
    209       EIGEN_ONLY_USED_FOR_DEBUG(size);
    210       eigen_assert(size == this->size()
    211                 && "DenseBase::resize() does not actually allow to resize.");
    212     }
    213     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
    214       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
    215       * nothing else.
    216       */
    217     void resize(Index rows, Index cols)
    218     {
    219       EIGEN_ONLY_USED_FOR_DEBUG(rows);
    220       EIGEN_ONLY_USED_FOR_DEBUG(cols);
    221       eigen_assert(rows == this->rows() && cols == this->cols()
    222                 && "DenseBase::resize() does not actually allow to resize.");
    223     }
    224 
    225 #ifndef EIGEN_PARSED_BY_DOXYGEN
    226 
    227     /** \internal Represents a matrix with all coefficients equal to one another*/
    228     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
    229     /** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */
    230     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
    231     /** \internal Represents a vector with linearly spaced coefficients that allows random access. */
    232     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType;
    233     /** \internal the return type of MatrixBase::eigenvalues() */
    234     typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
    235 
    236 #endif // not EIGEN_PARSED_BY_DOXYGEN
    237 
    238     /** Copies \a other into *this. \returns a reference to *this. */
    239     template<typename OtherDerived>
    240     Derived& operator=(const DenseBase<OtherDerived>& other);
    241 
    242     /** Special case of the template operator=, in order to prevent the compiler
    243       * from generating a default operator= (issue hit with g++ 4.1)
    244       */
    245     Derived& operator=(const DenseBase& other);
    246 
    247     template<typename OtherDerived>
    248     Derived& operator=(const EigenBase<OtherDerived> &other);
    249 
    250     template<typename OtherDerived>
    251     Derived& operator+=(const EigenBase<OtherDerived> &other);
    252 
    253     template<typename OtherDerived>
    254     Derived& operator-=(const EigenBase<OtherDerived> &other);
    255 
    256     template<typename OtherDerived>
    257     Derived& operator=(const ReturnByValue<OtherDerived>& func);
    258 
    259 #ifndef EIGEN_PARSED_BY_DOXYGEN
    260     /** Copies \a other into *this without evaluating other. \returns a reference to *this. */
    261     template<typename OtherDerived>
    262     Derived& lazyAssign(const DenseBase<OtherDerived>& other);
    263 #endif // not EIGEN_PARSED_BY_DOXYGEN
    264 
    265     CommaInitializer<Derived> operator<< (const Scalar& s);
    266 
    267     template<unsigned int Added,unsigned int Removed>
    268     const Flagged<Derived, Added, Removed> flagged() const;
    269 
    270     template<typename OtherDerived>
    271     CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
    272 
    273     Eigen::Transpose<Derived> transpose();
    274     typedef const Transpose<const Derived> ConstTransposeReturnType;
    275     ConstTransposeReturnType transpose() const;
    276     void transposeInPlace();
    277 #ifndef EIGEN_NO_DEBUG
    278   protected:
    279     template<typename OtherDerived>
    280     void checkTransposeAliasing(const OtherDerived& other) const;
    281   public:
    282 #endif
    283 
    284     typedef VectorBlock<Derived> SegmentReturnType;
    285     typedef const VectorBlock<const Derived> ConstSegmentReturnType;
    286     template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
    287     template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
    288 
    289     // Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
    290     SegmentReturnType segment(Index start, Index size);
    291     typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const;
    292 
    293     SegmentReturnType head(Index size);
    294     typename DenseBase::ConstSegmentReturnType head(Index size) const;
    295 
    296     SegmentReturnType tail(Index size);
    297     typename DenseBase::ConstSegmentReturnType tail(Index size) const;
    298 
    299     template<int Size> typename FixedSegmentReturnType<Size>::Type head();
    300     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type head() const;
    301 
    302     template<int Size> typename FixedSegmentReturnType<Size>::Type tail();
    303     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type tail() const;
    304 
    305     template<int Size> typename FixedSegmentReturnType<Size>::Type segment(Index start);
    306     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type segment(Index start) const;
    307 
    308     static const ConstantReturnType
    309     Constant(Index rows, Index cols, const Scalar& value);
    310     static const ConstantReturnType
    311     Constant(Index size, const Scalar& value);
    312     static const ConstantReturnType
    313     Constant(const Scalar& value);
    314 
    315     static const SequentialLinSpacedReturnType
    316     LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
    317     static const RandomAccessLinSpacedReturnType
    318     LinSpaced(Index size, const Scalar& low, const Scalar& high);
    319     static const SequentialLinSpacedReturnType
    320     LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
    321     static const RandomAccessLinSpacedReturnType
    322     LinSpaced(const Scalar& low, const Scalar& high);
    323 
    324     template<typename CustomNullaryOp>
    325     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    326     NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
    327     template<typename CustomNullaryOp>
    328     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    329     NullaryExpr(Index size, const CustomNullaryOp& func);
    330     template<typename CustomNullaryOp>
    331     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    332     NullaryExpr(const CustomNullaryOp& func);
    333 
    334     static const ConstantReturnType Zero(Index rows, Index cols);
    335     static const ConstantReturnType Zero(Index size);
    336     static const ConstantReturnType Zero();
    337     static const ConstantReturnType Ones(Index rows, Index cols);
    338     static const ConstantReturnType Ones(Index size);
    339     static const ConstantReturnType Ones();
    340 
    341     void fill(const Scalar& value);
    342     Derived& setConstant(const Scalar& value);
    343     Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
    344     Derived& setLinSpaced(const Scalar& low, const Scalar& high);
    345     Derived& setZero();
    346     Derived& setOnes();
    347     Derived& setRandom();
    348 
    349     template<typename OtherDerived>
    350     bool isApprox(const DenseBase<OtherDerived>& other,
    351                   RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    352     bool isMuchSmallerThan(const RealScalar& other,
    353                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    354     template<typename OtherDerived>
    355     bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
    356                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    357 
    358     bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    359     bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    360     bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    361     bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
    362 
    363     inline Derived& operator*=(const Scalar& other);
    364     inline Derived& operator/=(const Scalar& other);
    365 
    366     typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType;
    367     /** \returns the matrix or vector obtained by evaluating this expression.
    368       *
    369       * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
    370       * a const reference, in order to avoid a useless copy.
    371       */
    372     EIGEN_STRONG_INLINE EvalReturnType eval() const
    373     {
    374       // Even though MSVC does not honor strong inlining when the return type
    375       // is a dynamic matrix, we desperately need strong inlining for fixed
    376       // size types on MSVC.
    377       return typename internal::eval<Derived>::type(derived());
    378     }
    379 
    380     /** swaps *this with the expression \a other.
    381       *
    382       */
    383     template<typename OtherDerived>
    384     void swap(const DenseBase<OtherDerived>& other,
    385               int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
    386     {
    387       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
    388     }
    389 
    390     /** swaps *this with the matrix or array \a other.
    391       *
    392       */
    393     template<typename OtherDerived>
    394     void swap(PlainObjectBase<OtherDerived>& other)
    395     {
    396       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
    397     }
    398 
    399 
    400     inline const NestByValue<Derived> nestByValue() const;
    401     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
    402     inline ForceAlignedAccess<Derived> forceAlignedAccess();
    403     template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
    404     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
    405 
    406     Scalar sum() const;
    407     Scalar mean() const;
    408     Scalar trace() const;
    409 
    410     Scalar prod() const;
    411 
    412     typename internal::traits<Derived>::Scalar minCoeff() const;
    413     typename internal::traits<Derived>::Scalar maxCoeff() const;
    414 
    415     template<typename IndexType>
    416     typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
    417     template<typename IndexType>
    418     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
    419     template<typename IndexType>
    420     typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
    421     template<typename IndexType>
    422     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
    423 
    424     template<typename BinaryOp>
    425     typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type
    426     redux(const BinaryOp& func) const;
    427 
    428     template<typename Visitor>
    429     void visit(Visitor& func) const;
    430 
    431     inline const WithFormat<Derived> format(const IOFormat& fmt) const;
    432 
    433     /** \returns the unique coefficient of a 1x1 expression */
    434     CoeffReturnType value() const
    435     {
    436       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
    437       eigen_assert(this->rows() == 1 && this->cols() == 1);
    438       return derived().coeff(0,0);
    439     }
    440 
    441 /////////// Array module ///////////
    442 
    443     bool all(void) const;
    444     bool any(void) const;
    445     Index count() const;
    446 
    447     typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
    448     typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
    449     typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
    450     typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
    451 
    452     ConstRowwiseReturnType rowwise() const;
    453     RowwiseReturnType rowwise();
    454     ConstColwiseReturnType colwise() const;
    455     ColwiseReturnType colwise();
    456 
    457     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols);
    458     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size);
    459     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random();
    460 
    461     template<typename ThenDerived,typename ElseDerived>
    462     const Select<Derived,ThenDerived,ElseDerived>
    463     select(const DenseBase<ThenDerived>& thenMatrix,
    464            const DenseBase<ElseDerived>& elseMatrix) const;
    465 
    466     template<typename ThenDerived>
    467     inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
    468     select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
    469 
    470     template<typename ElseDerived>
    471     inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
    472     select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
    473 
    474     template<int p> RealScalar lpNorm() const;
    475 
    476     template<int RowFactor, int ColFactor>
    477     const Replicate<Derived,RowFactor,ColFactor> replicate() const;
    478     const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
    479 
    480     typedef Reverse<Derived, BothDirections> ReverseReturnType;
    481     typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
    482     ReverseReturnType reverse();
    483     ConstReverseReturnType reverse() const;
    484     void reverseInPlace();
    485 
    486 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
    487 #   include "../plugins/BlockMethods.h"
    488 #   ifdef EIGEN_DENSEBASE_PLUGIN
    489 #     include EIGEN_DENSEBASE_PLUGIN
    490 #   endif
    491 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
    492 
    493 #ifdef EIGEN2_SUPPORT
    494 
    495     Block<Derived> corner(CornerType type, Index cRows, Index cCols);
    496     const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const;
    497     template<int CRows, int CCols>
    498     Block<Derived, CRows, CCols> corner(CornerType type);
    499     template<int CRows, int CCols>
    500     const Block<Derived, CRows, CCols> corner(CornerType type) const;
    501 
    502 #endif // EIGEN2_SUPPORT
    503 
    504 
    505     // disable the use of evalTo for dense objects with a nice compilation error
    506     template<typename Dest> inline void evalTo(Dest& ) const
    507     {
    508       EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
    509     }
    510 
    511   protected:
    512     /** Default constructor. Do nothing. */
    513     DenseBase()
    514     {
    515       /* Just checks for self-consistency of the flags.
    516        * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
    517        */
    518 #ifdef EIGEN_INTERNAL_DEBUGGING
    519       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
    520                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
    521                           INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
    522 #endif
    523     }
    524 
    525   private:
    526     explicit DenseBase(int);
    527     DenseBase(int,int);
    528     template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&);
    529 };
    530 
    531 } // end namespace Eigen
    532 
    533 #endif // EIGEN_DENSEBASE_H
    534