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