Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef EIGEN_REVERSE_H
00013 #define EIGEN_REVERSE_H
00014
00015 namespace Eigen {
00016
00031 namespace internal {
00032
00033 template<typename MatrixType, int Direction>
00034 struct traits<Reverse<MatrixType, Direction> >
00035 : traits<MatrixType>
00036 {
00037 typedef typename MatrixType::Scalar Scalar;
00038 typedef typename traits<MatrixType>::StorageKind StorageKind;
00039 typedef typename traits<MatrixType>::XprKind XprKind;
00040 typedef typename nested<MatrixType>::type MatrixTypeNested;
00041 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
00042 enum {
00043 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00044 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
00045 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00046 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00047
00048
00049 LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
00050 ? LinearAccessBit : 0,
00051
00052 Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
00053
00054 CoeffReadCost = _MatrixTypeNested::CoeffReadCost
00055 };
00056 };
00057
00058 template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
00059 {
00060 static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
00061 };
00062
00063 template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
00064 {
00065 static inline PacketScalar run(const PacketScalar& x) { return x; }
00066 };
00067
00068 }
00069
00070 template<typename MatrixType, int Direction> class Reverse
00071 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
00072 {
00073 public:
00074
00075 typedef typename internal::dense_xpr_base<Reverse>::type Base;
00076 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
00077 using Base::IsRowMajor;
00078
00079
00080
00081 using Base::operator();
00082
00083 protected:
00084 enum {
00085 PacketSize = internal::packet_traits<Scalar>::size,
00086 IsColMajor = !IsRowMajor,
00087 ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
00088 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
00089 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
00090 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
00091 ReversePacket = (Direction == BothDirections)
00092 || ((Direction == Vertical) && IsColMajor)
00093 || ((Direction == Horizontal) && IsRowMajor)
00094 };
00095 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
00096 public:
00097
00098 inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
00099
00100 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
00101
00102 inline Index rows() const { return m_matrix.rows(); }
00103 inline Index cols() const { return m_matrix.cols(); }
00104
00105 inline Index innerStride() const
00106 {
00107 return -m_matrix.innerStride();
00108 }
00109
00110 inline Scalar& operator()(Index row, Index col)
00111 {
00112 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
00113 return coeffRef(row, col);
00114 }
00115
00116 inline Scalar& coeffRef(Index row, Index col)
00117 {
00118 return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
00119 ReverseCol ? m_matrix.cols() - col - 1 : col);
00120 }
00121
00122 inline CoeffReturnType coeff(Index row, Index col) const
00123 {
00124 return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
00125 ReverseCol ? m_matrix.cols() - col - 1 : col);
00126 }
00127
00128 inline CoeffReturnType coeff(Index index) const
00129 {
00130 return m_matrix.coeff(m_matrix.size() - index - 1);
00131 }
00132
00133 inline Scalar& coeffRef(Index index)
00134 {
00135 return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
00136 }
00137
00138 inline Scalar& operator()(Index index)
00139 {
00140 eigen_assert(index >= 0 && index < m_matrix.size());
00141 return coeffRef(index);
00142 }
00143
00144 template<int LoadMode>
00145 inline const PacketScalar packet(Index row, Index col) const
00146 {
00147 return reverse_packet::run(m_matrix.template packet<LoadMode>(
00148 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00149 ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
00150 }
00151
00152 template<int LoadMode>
00153 inline void writePacket(Index row, Index col, const PacketScalar& x)
00154 {
00155 m_matrix.const_cast_derived().template writePacket<LoadMode>(
00156 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00157 ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
00158 reverse_packet::run(x));
00159 }
00160
00161 template<int LoadMode>
00162 inline const PacketScalar packet(Index index) const
00163 {
00164 return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
00165 }
00166
00167 template<int LoadMode>
00168 inline void writePacket(Index index, const PacketScalar& x)
00169 {
00170 m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
00171 }
00172
00173 const typename internal::remove_all<typename MatrixType::Nested>::type&
00174 nestedExpression() const
00175 {
00176 return m_matrix;
00177 }
00178
00179 protected:
00180 typename MatrixType::Nested m_matrix;
00181 };
00182
00189 template<typename Derived>
00190 inline typename DenseBase<Derived>::ReverseReturnType
00191 DenseBase<Derived>::reverse()
00192 {
00193 return derived();
00194 }
00195
00197 template<typename Derived>
00198 inline const typename DenseBase<Derived>::ConstReverseReturnType
00199 DenseBase<Derived>::reverse() const
00200 {
00201 return derived();
00202 }
00203
00216 template<typename Derived>
00217 inline void DenseBase<Derived>::reverseInPlace()
00218 {
00219 derived() = derived().reverse().eval();
00220 }
00221
00222 }
00223
00224 #endif // EIGEN_REVERSE_H