Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / MapBase.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 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25
26 #ifndef EIGEN_MAPBASE_H
27 #define EIGEN_MAPBASE_H
28
29 /** \class MapBase
30   *
31   * \brief Base class for Map and Block expression with direct access
32   *
33   * Expression classes inheriting MapBase must define the constant \c PacketAccess,
34   * and type \c AlignedDerivedType in their respective ei_traits<> specialization structure.
35   * The value of \c PacketAccess can be either:
36   *  - \b ForceAligned which enforces both aligned loads and stores
37   *  - \b AsRequested which is the default behavior
38   * The type \c AlignedDerivedType should correspond to the equivalent expression type
39   * with \c PacketAccess being \c ForceAligned.
40   *
41   * \sa class Map, class Block
42   */
43 template<typename Derived> class MapBase
44   : public MatrixBase<Derived>
45 {
46   public:
47
48     typedef MatrixBase<Derived> Base;
49     enum {
50       IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0,
51       PacketAccess = ei_traits<Derived>::PacketAccess,
52       RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
53       ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
54       SizeAtCompileTime = Base::SizeAtCompileTime
55     };
56
57     typedef typename ei_traits<Derived>::AlignedDerivedType AlignedDerivedType;
58     typedef typename ei_traits<Derived>::Scalar Scalar;
59     typedef typename Base::PacketScalar PacketScalar;
60     using Base::derived;
61
62     inline int rows() const { return m_rows.value(); }
63     inline int cols() const { return m_cols.value(); }
64
65     inline int stride() const { return derived().stride(); }
66     inline const Scalar* data() const { return m_data; }
67
68     template<bool IsForceAligned,typename Dummy> struct force_aligned_impl {
69       AlignedDerivedType static run(MapBase& a) { return a.derived(); }
70     };
71
72     template<typename Dummy> struct force_aligned_impl<false,Dummy> {
73       AlignedDerivedType static run(MapBase& a) { return a.derived()._convertToForceAligned(); }
74     };
75
76     /** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
77       * set to \c ForceAligned. Must be reimplemented by the derived class. */
78     AlignedDerivedType forceAligned()
79     {
80       return force_aligned_impl<int(PacketAccess)==int(ForceAligned),Derived>::run(*this);
81     }
82
83     inline const Scalar& coeff(int row, int col) const
84     {
85       if(IsRowMajor)
86         return m_data[col + row * stride()];
87       else // column-major
88         return m_data[row + col * stride()];
89     }
90
91     inline Scalar& coeffRef(int row, int col)
92     {
93       if(IsRowMajor)
94         return const_cast<Scalar*>(m_data)[col + row * stride()];
95       else // column-major
96         return const_cast<Scalar*>(m_data)[row + col * stride()];
97     }
98
99     inline const Scalar coeff(int index) const
100     {
101       ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
102       if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
103         return m_data[index];
104       else
105         return m_data[index*stride()];
106     }
107
108     inline Scalar& coeffRef(int index)
109     {
110       ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
111       if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
112         return const_cast<Scalar*>(m_data)[index];
113       else
114         return const_cast<Scalar*>(m_data)[index*stride()];
115     }
116
117     template<int LoadMode>
118     inline PacketScalar packet(int row, int col) const
119     {
120       return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>
121                (m_data + (IsRowMajor ? col + row * stride()
122                                      : row + col * stride()));
123     }
124
125     template<int LoadMode>
126     inline PacketScalar packet(int index) const
127     {
128       return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>(m_data + index);
129     }
130
131     template<int StoreMode>
132     inline void writePacket(int row, int col, const PacketScalar& x)
133     {
134       ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
135                (const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride()
136                                                           : row + col * stride()), x);
137     }
138
139     template<int StoreMode>
140     inline void writePacket(int index, const PacketScalar& x)
141     {
142       ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
143         (const_cast<Scalar*>(m_data) + index, x);
144     }
145
146     inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
147     {
148       EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
149     }
150
151     inline MapBase(const Scalar* data, int size)
152             : m_data(data),
153               m_rows(RowsAtCompileTime == Dynamic ? size : RowsAtCompileTime),
154               m_cols(ColsAtCompileTime == Dynamic ? size : ColsAtCompileTime)
155     {
156       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
157       ei_assert(size > 0 || data == 0);
158       ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
159     }
160
161     inline MapBase(const Scalar* data, int rows, int cols)
162             : m_data(data), m_rows(rows), m_cols(cols)
163     {
164       ei_assert( (data == 0)
165               || (   rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
166                   && cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
167     }
168
169     Derived& operator=(const MapBase& other)
170     {
171       return Base::operator=(other);
172     }
173
174     template<typename OtherDerived>
175     Derived& operator=(const MatrixBase<OtherDerived>& other)
176     {
177       return Base::operator=(other);
178     }
179     
180     using Base::operator*=;
181
182     template<typename OtherDerived>
183     Derived& operator+=(const MatrixBase<OtherDerived>& other)
184     { return derived() = forceAligned() + other; }
185
186     template<typename OtherDerived>
187     Derived& operator-=(const MatrixBase<OtherDerived>& other)
188     { return derived() = forceAligned() - other; }
189
190     Derived& operator*=(const Scalar& other)
191     { return derived() = forceAligned() * other; }
192
193     Derived& operator/=(const Scalar& other)
194     { return derived() = forceAligned() / other; }
195
196   protected:
197     const Scalar* EIGEN_RESTRICT m_data;
198     const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
199     const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
200 };
201
202 #endif // EIGEN_MAPBASE_H