Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / Swap.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
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_SWAP_H
26 #define EIGEN_SWAP_H
27
28 /** \class SwapWrapper
29   *
30   * \internal
31   *
32   * \brief Internal helper class for swapping two expressions
33   */
34 template<typename ExpressionType>
35 struct ei_traits<SwapWrapper<ExpressionType> >
36 {
37   typedef typename ExpressionType::Scalar Scalar;
38   enum {
39     RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
40     ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
41     MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
42     MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
43     Flags = ExpressionType::Flags,
44     CoeffReadCost = ExpressionType::CoeffReadCost
45   };
46 };
47
48 template<typename ExpressionType> class SwapWrapper
49   : public MatrixBase<SwapWrapper<ExpressionType> >
50 {
51   public:
52
53     EIGEN_GENERIC_PUBLIC_INTERFACE(SwapWrapper)
54     typedef typename ei_packet_traits<Scalar>::type Packet;
55
56     inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}
57
58     inline int rows() const { return m_expression.rows(); }
59     inline int cols() const { return m_expression.cols(); }
60     inline int stride() const { return m_expression.stride(); }
61
62     inline Scalar& coeffRef(int row, int col)
63     {
64       return m_expression.const_cast_derived().coeffRef(row, col);
65     }
66
67     inline Scalar& coeffRef(int index)
68     {
69       return m_expression.const_cast_derived().coeffRef(index);
70     }
71
72     template<typename OtherDerived>
73     void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
74     {
75       OtherDerived& _other = other.const_cast_derived();
76       ei_internal_assert(row >= 0 && row < rows()
77                          && col >= 0 && col < cols());
78       Scalar tmp = m_expression.coeff(row, col);
79       m_expression.coeffRef(row, col) = _other.coeff(row, col);
80       _other.coeffRef(row, col) = tmp;
81     }
82
83     template<typename OtherDerived>
84     void copyCoeff(int index, const MatrixBase<OtherDerived>& other)
85     {
86       OtherDerived& _other = other.const_cast_derived();
87       ei_internal_assert(index >= 0 && index < m_expression.size());
88       Scalar tmp = m_expression.coeff(index);
89       m_expression.coeffRef(index) = _other.coeff(index);
90       _other.coeffRef(index) = tmp;
91     }
92
93     template<typename OtherDerived, int StoreMode, int LoadMode>
94     void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
95     {
96       OtherDerived& _other = other.const_cast_derived();
97       ei_internal_assert(row >= 0 && row < rows()
98                         && col >= 0 && col < cols());
99       Packet tmp = m_expression.template packet<StoreMode>(row, col);
100       m_expression.template writePacket<StoreMode>(row, col,
101         _other.template packet<LoadMode>(row, col)
102       );
103       _other.template writePacket<LoadMode>(row, col, tmp);
104     }
105
106     template<typename OtherDerived, int StoreMode, int LoadMode>
107     void copyPacket(int index, const MatrixBase<OtherDerived>& other)
108     {
109       OtherDerived& _other = other.const_cast_derived();
110       ei_internal_assert(index >= 0 && index < m_expression.size());
111       Packet tmp = m_expression.template packet<StoreMode>(index);
112       m_expression.template writePacket<StoreMode>(index,
113         _other.template packet<LoadMode>(index)
114       );
115       _other.template writePacket<LoadMode>(index, tmp);
116     }
117
118   protected:
119     ExpressionType& m_expression;
120 };
121
122 /** swaps *this with the expression \a other.
123   *
124   * \note \a other is only marked for internal reasons, but of course
125   * it gets const-casted. One reason is that one will often call swap
126   * on temporary objects (hence non-const references are forbidden).
127   * Another reason is that lazyAssign takes a const argument anyway.
128   */
129 template<typename Derived>
130 template<typename OtherDerived>
131 void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
132 {
133   (SwapWrapper<Derived>(derived())).lazyAssign(other);
134 }
135
136 #endif // EIGEN_SWAP_H
137
138
139
140
141
142