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
13namespace 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 */
30template<typename ExpressionType, template <typename> class StorageBase>
31class 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 */
100template<typename Derived>
101NoAlias<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