Block.h 17.6 KB
Newer Older
LM's avatar
LM committed
1 2 3 4 5 6
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
Don Gagne's avatar
Don Gagne committed
7 8 9
// 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/.
LM's avatar
LM committed
10 11 12 13

#ifndef EIGEN_BLOCK_H
#define EIGEN_BLOCK_H

Don Gagne's avatar
Don Gagne committed
14 15
namespace Eigen { 

LM's avatar
LM committed
16
namespace internal {
Don Gagne's avatar
Don Gagne committed
17 18
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType>
LM's avatar
LM committed
19 20 21 22
{
  typedef typename traits<XprType>::Scalar Scalar;
  typedef typename traits<XprType>::StorageKind StorageKind;
  typedef typename traits<XprType>::XprKind XprKind;
23
  typedef typename ref_selector<XprType>::type XprTypeNested;
LM's avatar
LM committed
24 25 26 27 28 29 30 31 32 33 34 35
  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
  enum{
    MatrixRows = traits<XprType>::RowsAtCompileTime,
    MatrixCols = traits<XprType>::ColsAtCompileTime,
    RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
    ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
    MaxRowsAtCompileTime = BlockRows==0 ? 0
                         : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
                         : int(traits<XprType>::MaxRowsAtCompileTime),
    MaxColsAtCompileTime = BlockCols==0 ? 0
                         : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
                         : int(traits<XprType>::MaxColsAtCompileTime),
36

LM's avatar
LM committed
37
    XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
38 39
    IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
               : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
LM's avatar
LM committed
40 41 42 43 44 45 46 47 48
               : XprTypeIsRowMajor,
    HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
    InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
    InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
                             ? int(inner_stride_at_compile_time<XprType>::ret)
                             : int(outer_stride_at_compile_time<XprType>::ret),
    OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
                             ? int(outer_stride_at_compile_time<XprType>::ret)
                             : int(inner_stride_at_compile_time<XprType>::ret),
49 50

    // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
LM's avatar
LM committed
51 52
    FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
    FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
53 54 55 56 57 58
    Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
    // FIXME DirectAccessBit should not be handled by expressions
    // 
    // Alignment is needed by MapBase's assertions
    // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
    Alignment = 0
LM's avatar
LM committed
59 60 61
  };
};

Don Gagne's avatar
Don Gagne committed
62 63 64 65
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
         bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
         
} // end namespace internal
LM's avatar
LM committed
66

Don Gagne's avatar
Don Gagne committed
67
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
LM's avatar
LM committed
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/** \class Block
  * \ingroup Core_Module
  *
  * \brief Expression of a fixed-size or dynamic-size block
  *
  * \tparam XprType the type of the expression in which we are taking a block
  * \tparam BlockRows the number of rows of the block we are taking at compile time (optional)
  * \tparam BlockCols the number of columns of the block we are taking at compile time (optional)
  * \tparam InnerPanel is true, if the block maps to a set of rows of a row major matrix or
  *         to set of columns of a column major matrix (optional). The parameter allows to determine
  *         at compile time whether aligned access is possible on the block expression.
  *
  * This class represents an expression of either a fixed-size or dynamic-size block. It is the return
  * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
  * most of the time this is the only way it is used.
  *
  * However, if you want to directly maniputate block expressions,
  * for instance if you want to write a function returning such an expression, you
  * will need to use this class.
  *
  * Here is an example illustrating the dynamic case:
  * \include class_Block.cpp
  * Output: \verbinclude class_Block.out
  *
  * \note Even though this expression has dynamic size, in the case where \a XprType
  * has fixed size, this expression inherits a fixed maximal size which means that evaluating
  * it does not cause a dynamic memory allocation.
  *
  * Here is an example illustrating the fixed-size case:
  * \include class_FixedBlock.cpp
  * Output: \verbinclude class_FixedBlock.out
  *
  * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
  */
Don Gagne's avatar
Don Gagne committed
103 104 105 106 107 108 109 110 111
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
  : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
{
    typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
  public:
    //typedef typename Impl::Base Base;
    typedef Impl Base;
    EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
112 113
    
    typedef typename internal::remove_all<XprType>::type NestedExpression;
Don Gagne's avatar
Don Gagne committed
114
  
LM's avatar
LM committed
115 116
    /** Column or Row constructor
      */
117
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
118
    inline Block(XprType& xpr, Index i) : Impl(xpr,i)
LM's avatar
LM committed
119 120 121 122 123 124 125 126
    {
      eigen_assert( (i>=0) && (
          ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
        ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
    }

    /** Fixed-size constructor
      */
127 128 129
    EIGEN_DEVICE_FUNC
    inline Block(XprType& xpr, Index startRow, Index startCol)
      : Impl(xpr, startRow, startCol)
LM's avatar
LM committed
130 131
    {
      EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
132 133
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows()
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
LM's avatar
LM committed
134 135 136 137
    }

    /** Dynamic-size constructor
      */
138
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
139
    inline Block(XprType& xpr,
140
          Index startRow, Index startCol,
LM's avatar
LM committed
141
          Index blockRows, Index blockCols)
142
      : Impl(xpr, startRow, startCol, blockRows, blockCols)
LM's avatar
LM committed
143 144 145
    {
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
146 147
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= xpr.rows() - blockRows
          && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
LM's avatar
LM committed
148
    }
Don Gagne's avatar
Don Gagne committed
149 150 151 152 153 154 155 156 157
};
         
// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
// that must be specialized for direct and non-direct access...
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
{
    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
158
    typedef typename XprType::StorageIndex StorageIndex;
Don Gagne's avatar
Don Gagne committed
159 160 161
  public:
    typedef Impl Base;
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
162 163 164 165 166
    EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
    EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
    EIGEN_DEVICE_FUNC
    inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
      : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
Don Gagne's avatar
Don Gagne committed
167
};
LM's avatar
LM committed
168

Don Gagne's avatar
Don Gagne committed
169 170 171 172 173 174 175
namespace internal {

/** \internal Internal implementation of dense Blocks in the general case. */
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
  : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
{
    typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
176
    typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
Don Gagne's avatar
Don Gagne committed
177 178 179 180 181 182
  public:

    typedef typename internal::dense_xpr_base<BlockType>::type Base;
    EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)

183
    // class InnerIterator; // FIXME apparently never used
Don Gagne's avatar
Don Gagne committed
184 185 186

    /** Column or Row constructor
      */
187
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201
    inline BlockImpl_dense(XprType& xpr, Index i)
      : m_xpr(xpr),
        // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
        // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
        // all other cases are invalid.
        // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
        m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
        m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
        m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
        m_blockCols(BlockCols==1 ? 1 : xpr.cols())
    {}

    /** Fixed-size constructor
      */
202 203 204
    EIGEN_DEVICE_FUNC
    inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
Don Gagne's avatar
Don Gagne committed
205 206 207 208 209
                    m_blockRows(BlockRows), m_blockCols(BlockCols)
    {}

    /** Dynamic-size constructor
      */
210
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
211
    inline BlockImpl_dense(XprType& xpr,
212
          Index startRow, Index startCol,
Don Gagne's avatar
Don Gagne committed
213
          Index blockRows, Index blockCols)
214
      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
Don Gagne's avatar
Don Gagne committed
215 216
                    m_blockRows(blockRows), m_blockCols(blockCols)
    {}
LM's avatar
LM committed
217

218 219
    EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
    EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
LM's avatar
LM committed
220

221
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
222
    inline Scalar& coeffRef(Index rowId, Index colId)
LM's avatar
LM committed
223 224
    {
      EIGEN_STATIC_ASSERT_LVALUE(XprType)
225
      return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
LM's avatar
LM committed
226 227
    }

228
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
229
    inline const Scalar& coeffRef(Index rowId, Index colId) const
LM's avatar
LM committed
230
    {
231
      return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
LM's avatar
LM committed
232 233
    }

234
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
235
    EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
LM's avatar
LM committed
236
    {
Don Gagne's avatar
Don Gagne committed
237
      return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
LM's avatar
LM committed
238 239
    }

240
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
241 242 243
    inline Scalar& coeffRef(Index index)
    {
      EIGEN_STATIC_ASSERT_LVALUE(XprType)
244 245
      return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                            m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
LM's avatar
LM committed
246 247
    }

248
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
249 250
    inline const Scalar& coeffRef(Index index) const
    {
251 252
      return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                            m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
LM's avatar
LM committed
253 254
    }

255
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
256 257
    inline const CoeffReturnType coeff(Index index) const
    {
258 259
      return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                         m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
LM's avatar
LM committed
260 261 262
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
263
    inline PacketScalar packet(Index rowId, Index colId) const
LM's avatar
LM committed
264
    {
265
      return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
LM's avatar
LM committed
266 267 268
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
269
    inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
LM's avatar
LM committed
270
    {
271
      m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
LM's avatar
LM committed
272 273 274 275 276 277 278 279 280 281 282
    }

    template<int LoadMode>
    inline PacketScalar packet(Index index) const
    {
      return m_xpr.template packet<Unaligned>
              (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
               m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
283
    inline void writePacket(Index index, const PacketScalar& val)
LM's avatar
LM committed
284
    {
285
      m_xpr.template writePacket<Unaligned>
LM's avatar
LM committed
286
         (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
Don Gagne's avatar
Don Gagne committed
287
          m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
LM's avatar
LM committed
288 289 290 291
    }

    #ifdef EIGEN_PARSED_BY_DOXYGEN
    /** \sa MapBase::data() */
292 293 294
    EIGEN_DEVICE_FUNC inline const Scalar* data() const;
    EIGEN_DEVICE_FUNC inline Index innerStride() const;
    EIGEN_DEVICE_FUNC inline Index outerStride() const;
LM's avatar
LM committed
295 296
    #endif

297 298
    EIGEN_DEVICE_FUNC
    const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
Don Gagne's avatar
Don Gagne committed
299 300 301
    { 
      return m_xpr; 
    }
302 303 304

    EIGEN_DEVICE_FUNC
    XprType& nestedExpression() { return m_xpr; }
Don Gagne's avatar
Don Gagne committed
305
      
306 307
    EIGEN_DEVICE_FUNC
    StorageIndex startRow() const
Don Gagne's avatar
Don Gagne committed
308 309 310 311
    { 
      return m_startRow.value(); 
    }
      
312 313
    EIGEN_DEVICE_FUNC
    StorageIndex startCol() const
Don Gagne's avatar
Don Gagne committed
314 315 316 317
    { 
      return m_startCol.value(); 
    }

LM's avatar
LM committed
318 319
  protected:

320 321 322 323 324
    XprTypeNested m_xpr;
    const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
    const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
    const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
    const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
LM's avatar
LM committed
325 326
};

Don Gagne's avatar
Don Gagne committed
327
/** \internal Internal implementation of dense Blocks in the direct access case.*/
LM's avatar
LM committed
328
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
Don Gagne's avatar
Don Gagne committed
329 330
class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
  : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
LM's avatar
LM committed
331
{
Don Gagne's avatar
Don Gagne committed
332
    typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
333 334 335 336
    typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
    enum {
      XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
    };
LM's avatar
LM committed
337 338
  public:

Don Gagne's avatar
Don Gagne committed
339 340 341
    typedef MapBase<BlockType> Base;
    EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
LM's avatar
LM committed
342 343 344

    /** Column or Row constructor
      */
345
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
346
    inline BlockImpl_dense(XprType& xpr, Index i)
347 348
      : Base(xpr.data() + i * (    ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) 
                                || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
LM's avatar
LM committed
349 350
             BlockRows==1 ? 1 : xpr.rows(),
             BlockCols==1 ? 1 : xpr.cols()),
351 352 353
        m_xpr(xpr),
        m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
        m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)
LM's avatar
LM committed
354 355 356 357 358 359
    {
      init();
    }

    /** Fixed-size constructor
      */
360
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
361
    inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
362 363
      : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
        m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
LM's avatar
LM committed
364 365 366 367 368 369
    {
      init();
    }

    /** Dynamic-size constructor
      */
370
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
371
    inline BlockImpl_dense(XprType& xpr,
LM's avatar
LM committed
372 373
          Index startRow, Index startCol,
          Index blockRows, Index blockCols)
374 375
      : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
        m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
LM's avatar
LM committed
376 377 378 379
    {
      init();
    }

380 381
    EIGEN_DEVICE_FUNC
    const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
Don Gagne's avatar
Don Gagne committed
382 383 384
    { 
      return m_xpr; 
    }
385 386 387

    EIGEN_DEVICE_FUNC
    XprType& nestedExpression() { return m_xpr; }
Don Gagne's avatar
Don Gagne committed
388
      
LM's avatar
LM committed
389
    /** \sa MapBase::innerStride() */
390
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
391 392
    inline Index innerStride() const
    {
Don Gagne's avatar
Don Gagne committed
393
      return internal::traits<BlockType>::HasSameStorageOrderAsXprType
LM's avatar
LM committed
394 395 396 397 398
             ? m_xpr.innerStride()
             : m_xpr.outerStride();
    }

    /** \sa MapBase::outerStride() */
399
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
400 401 402 403 404
    inline Index outerStride() const
    {
      return m_outerStride;
    }

405 406 407 408 409 410 411 412 413 414 415 416
    EIGEN_DEVICE_FUNC
    StorageIndex startRow() const
    {
      return m_startRow.value();
    }

    EIGEN_DEVICE_FUNC
    StorageIndex startCol() const
    {
      return m_startCol.value();
    }

LM's avatar
LM committed
417 418 419 420 421 422 423 424
  #ifndef __SUNPRO_CC
  // FIXME sunstudio is not friendly with the above friend...
  // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
  protected:
  #endif

    #ifndef EIGEN_PARSED_BY_DOXYGEN
    /** \internal used by allowAligned() */
425
    EIGEN_DEVICE_FUNC
Don Gagne's avatar
Don Gagne committed
426
    inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
LM's avatar
LM committed
427 428 429 430 431 432 433
      : Base(data, blockRows, blockCols), m_xpr(xpr)
    {
      init();
    }
    #endif

  protected:
434
    EIGEN_DEVICE_FUNC
LM's avatar
LM committed
435 436
    void init()
    {
Don Gagne's avatar
Don Gagne committed
437
      m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
LM's avatar
LM committed
438 439 440 441
                    ? m_xpr.outerStride()
                    : m_xpr.innerStride();
    }

442 443 444
    XprTypeNested m_xpr;
    const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
    const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
Don Gagne's avatar
Don Gagne committed
445
    Index m_outerStride;
LM's avatar
LM committed
446 447
};

Don Gagne's avatar
Don Gagne committed
448 449 450
} // end namespace internal

} // end namespace Eigen
LM's avatar
LM committed
451 452

#endif // EIGEN_BLOCK_H