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 // 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
NoAlias(ExpressionType & expression)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
expression()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>
noalias()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