1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud (at) inria.fr> 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_NOALIAS_H 11 #define EIGEN_NOALIAS_H 12 13 namespace Eigen { 14 15 /** \class NoAlias 16 * \ingroup Core_Module 17 * 18 * \brief Pseudo expression providing an operator = assuming no aliasing 19 * 20 * \tparam ExpressionType the type of the object on which to do the lazy assignment 21 * 22 * This class represents an expression with special assignment operators 23 * assuming no aliasing between the target expression and the source expression. 24 * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. 25 * It is the return type of MatrixBase::noalias() 26 * and most of the time this is the only way it is used. 27 * 28 * \sa MatrixBase::noalias() 29 */ 30 template<typename ExpressionType, template <typename> class StorageBase> 31 class NoAlias 32 { 33 public: 34 typedef typename ExpressionType::Scalar Scalar; 35 36 explicit NoAlias(ExpressionType& expression) : m_expression(expression) {} 37 38 template<typename OtherDerived> 39 EIGEN_DEVICE_FUNC 40 EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) 41 { 42 call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>()); 43 return m_expression; 44 } 45 46 template<typename OtherDerived> 47 EIGEN_DEVICE_FUNC 48 EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) 49 { 50 call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>()); 51 return m_expression; 52 } 53 54 template<typename OtherDerived> 55 EIGEN_DEVICE_FUNC 56 EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other) 57 { 58 call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>()); 59 return m_expression; 60 } 61 62 EIGEN_DEVICE_FUNC 63 ExpressionType& expression() const 64 { 65 return m_expression; 66 } 67 68 protected: 69 ExpressionType& m_expression; 70 }; 71 72 /** \returns a pseudo expression of \c *this with an operator= assuming 73 * no aliasing between \c *this and the source expression. 74 * 75 * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. 76 * Currently, even though several expressions may alias, only product 77 * expressions have this flag. Therefore, noalias() is only usefull when 78 * the source expression contains a matrix product. 79 * 80 * Here are some examples where noalias is usefull: 81 * \code 82 * D.noalias() = A * B; 83 * D.noalias() += A.transpose() * B; 84 * D.noalias() -= 2 * A * B.adjoint(); 85 * \endcode 86 * 87 * On the other hand the following example will lead to a \b wrong result: 88 * \code 89 * A.noalias() = A * B; 90 * \endcode 91 * because the result matrix A is also an operand of the matrix product. Therefore, 92 * there is no alternative than evaluating A * B in a temporary, that is the default 93 * behavior when you write: 94 * \code 95 * A = A * B; 96 * \endcode 97 * 98 * \sa class NoAlias 99 */ 100 template<typename Derived> 101 NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias() 102 { 103 return NoAlias<Derived, Eigen::MatrixBase >(derived()); 104 } 105 106 } // end namespace Eigen 107 108 #endif // EIGEN_NOALIAS_H 109