/src/Geometry_Eigen/Eigen/src/Core/NoAlias.h
C Header | 136 lines | 54 code | 12 blank | 70 comment | 0 complexity | 841fccf95f9a8590d2274d5cdaaca492 MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0
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@inria.fr> 5// 6// Eigen is free software; you can redistribute it and/or 7// modify it under the terms of the GNU Lesser General Public 8// License as published by the Free Software Foundation; either 9// version 3 of the License, or (at your option) any later version. 10// 11// Alternatively, you can redistribute it and/or 12// modify it under the terms of the GNU General Public License as 13// published by the Free Software Foundation; either version 2 of 14// the License, or (at your option) any later version. 15// 16// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY 17// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the 19// GNU General Public License for more details. 20// 21// You should have received a copy of the GNU Lesser General Public 22// License and a copy of the GNU General Public License along with 23// Eigen. If not, see <http://www.gnu.org/licenses/>. 24 25#ifndef EIGEN_NOALIAS_H 26#define EIGEN_NOALIAS_H 27 28/** \class NoAlias 29 * \ingroup Core_Module 30 * 31 * \brief Pseudo expression providing an operator = assuming no aliasing 32 * 33 * \param ExpressionType the type of the object on which to do the lazy assignment 34 * 35 * This class represents an expression with special assignment operators 36 * assuming no aliasing between the target expression and the source expression. 37 * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. 38 * It is the return type of MatrixBase::noalias() 39 * and most of the time this is the only way it is used. 40 * 41 * \sa MatrixBase::noalias() 42 */ 43template<typename ExpressionType, template <typename> class StorageBase> 44class NoAlias 45{ 46 typedef typename ExpressionType::Scalar Scalar; 47 public: 48 NoAlias(ExpressionType& expression) : m_expression(expression) {} 49 50 /** Behaves like MatrixBase::lazyAssign(other) 51 * \sa MatrixBase::lazyAssign() */ 52 template<typename OtherDerived> 53 EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) 54 { return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); } 55 56 /** \sa MatrixBase::operator+= */ 57 template<typename OtherDerived> 58 EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) 59 { 60 typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder; 61 SelfAdder tmp(m_expression); 62 typedef typename internal::nested<OtherDerived>::type OtherDerivedNested; 63 typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested; 64 internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived())); 65 return m_expression; 66 } 67 68 /** \sa MatrixBase::operator-= */ 69 template<typename OtherDerived> 70 EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other) 71 { 72 typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder; 73 SelfAdder tmp(m_expression); 74 typedef typename internal::nested<OtherDerived>::type OtherDerivedNested; 75 typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested; 76 internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived())); 77 return m_expression; 78 } 79 80#ifndef EIGEN_PARSED_BY_DOXYGEN 81 template<typename ProductDerived, typename Lhs, typename Rhs> 82 EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other) 83 { other.derived().addTo(m_expression); return m_expression; } 84 85 template<typename ProductDerived, typename Lhs, typename Rhs> 86 EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other) 87 { other.derived().subTo(m_expression); return m_expression; } 88 89 template<typename Lhs, typename Rhs, int NestingFlags> 90 EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other) 91 { return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); } 92 93 template<typename Lhs, typename Rhs, int NestingFlags> 94 EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other) 95 { return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); } 96#endif 97 98 protected: 99 ExpressionType& m_expression; 100}; 101 102/** \returns a pseudo expression of \c *this with an operator= assuming 103 * no aliasing between \c *this and the source expression. 104 * 105 * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. 106 * Currently, even though several expressions may alias, only product 107 * expressions have this flag. Therefore, noalias() is only usefull when 108 * the source expression contains a matrix product. 109 * 110 * Here are some examples where noalias is usefull: 111 * \code 112 * D.noalias() = A * B; 113 * D.noalias() += A.transpose() * B; 114 * D.noalias() -= 2 * A * B.adjoint(); 115 * \endcode 116 * 117 * On the other hand the following example will lead to a \b wrong result: 118 * \code 119 * A.noalias() = A * B; 120 * \endcode 121 * because the result matrix A is also an operand of the matrix product. Therefore, 122 * there is no alternative than evaluating A * B in a temporary, that is the default 123 * behavior when you write: 124 * \code 125 * A = A * B; 126 * \endcode 127 * 128 * \sa class NoAlias 129 */ 130template<typename Derived> 131NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias() 132{ 133 return derived(); 134} 135 136#endif // EIGEN_NOALIAS_H