1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2009-2010 Gael Guennebaud <[email protected]> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_FORCEALIGNEDACCESS_H 11 #define EIGEN_FORCEALIGNEDACCESS_H 12 13 namespace Eigen { 14 15 /** \class ForceAlignedAccess 16 * \ingroup Core_Module 17 * 18 * \brief Enforce aligned packet loads and stores regardless of what is requested 19 * 20 * \param ExpressionType the type of the object of which we are forcing aligned packet access 21 * 22 * This class is the return type of MatrixBase::forceAlignedAccess() 23 * and most of the time this is the only way it is used. 24 * 25 * \sa MatrixBase::forceAlignedAccess() 26 */ 27 28 namespace internal { 29 template<typename ExpressionType> 30 struct traits<ForceAlignedAccess<ExpressionType> > : public traits<ExpressionType> 31 {}; 32 } 33 34 template<typename ExpressionType> class ForceAlignedAccess 35 : public internal::dense_xpr_base< ForceAlignedAccess<ExpressionType> >::type 36 { 37 public: 38 39 typedef typename internal::dense_xpr_base<ForceAlignedAccess>::type Base; 40 EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess) 41 42 EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} 43 44 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 45 inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); } 46 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 47 inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); } 48 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 49 inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); } 50 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 51 inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); } 52 53 EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const 54 { 55 return m_expression.coeff(row, col); 56 } 57 58 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col) 59 { 60 return m_expression.const_cast_derived().coeffRef(row, col); 61 } 62 63 EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const 64 { 65 return m_expression.coeff(index); 66 } 67 68 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index) 69 { 70 return m_expression.const_cast_derived().coeffRef(index); 71 } 72 73 template<int LoadMode> 74 inline const PacketScalar packet(Index row, Index col) const 75 { 76 return m_expression.template packet<Aligned>(row, col); 77 } 78 79 template<int LoadMode> 80 inline void writePacket(Index row, Index col, const PacketScalar& x) 81 { 82 m_expression.const_cast_derived().template writePacket<Aligned>(row, col, x); 83 } 84 85 template<int LoadMode> 86 inline const PacketScalar packet(Index index) const 87 { 88 return m_expression.template packet<Aligned>(index); 89 } 90 91 template<int LoadMode> 92 inline void writePacket(Index index, const PacketScalar& x) 93 { 94 m_expression.const_cast_derived().template writePacket<Aligned>(index, x); 95 } 96 97 EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; } 98 99 protected: 100 const ExpressionType& m_expression; 101 102 private: 103 ForceAlignedAccess& operator=(const ForceAlignedAccess&); 104 }; 105 106 /** \returns an expression of *this with forced aligned access 107 * \sa forceAlignedAccessIf(),class ForceAlignedAccess 108 */ 109 template<typename Derived> 110 inline const ForceAlignedAccess<Derived> 111 MatrixBase<Derived>::forceAlignedAccess() const 112 { 113 return ForceAlignedAccess<Derived>(derived()); 114 } 115 116 /** \returns an expression of *this with forced aligned access 117 * \sa forceAlignedAccessIf(), class ForceAlignedAccess 118 */ 119 template<typename Derived> 120 inline ForceAlignedAccess<Derived> 121 MatrixBase<Derived>::forceAlignedAccess() 122 { 123 return ForceAlignedAccess<Derived>(derived()); 124 } 125 126 /** \returns an expression of *this with forced aligned access if \a Enable is true. 127 * \sa forceAlignedAccess(), class ForceAlignedAccess 128 */ 129 template<typename Derived> 130 template<bool Enable> 131 inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type 132 MatrixBase<Derived>::forceAlignedAccessIf() const 133 { 134 return derived(); // FIXME This should not work but apparently is never used 135 } 136 137 /** \returns an expression of *this with forced aligned access if \a Enable is true. 138 * \sa forceAlignedAccess(), class ForceAlignedAccess 139 */ 140 template<typename Derived> 141 template<bool Enable> 142 inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type 143 MatrixBase<Derived>::forceAlignedAccessIf() 144 { 145 return derived(); // FIXME This should not work but apparently is never used 146 } 147 148 } // end namespace Eigen 149 150 #endif // EIGEN_FORCEALIGNEDACCESS_H 151